0

我正在编写一些代码,其中我有一个抽象类,它有一些核心属性和一个 Run(int index) 方法。然后我创建继承它的新类型。这些新类型可以有多个可以根据传入的索引调用的方法。

public abstract class BaseClass
{
    public abstract void Run(int index);
}


public class Class1 : BaseClass
{

    public override void Run(int index)
    {
        if (index == 0)
        {
            MethodA(); 
        }
        else if (index == 1)
        {
            MethodB();
        }
    }

    private void MethodA()
    {
        //do stuff
    }

    private void MethodB()
    {
        //do stuff
    }
}

我只是想知道有没有更好的方法来做到这一点。这些类型和方法将从 UI 中调用,例如单击菜单。所以我可能有一个class1和一个class2。Class1 可能有 3 个方法,所以我可以调用 run(0) ... run(2) 。Class2 可能只有一个内部方法,所以我只调用 run(0)。也许我需要为我猜想的每个类保留一个整数集合作为方法的映射。可能还必须向此集合添加一个字符串来保存菜单项等的友好名称。

你能想出一种方法来实现这种类型的映射,同时尽可能多地保持抽象吗?有没有比我目前的想法更好的方法来解决这个问题?

4

3 回答 3

1

单程:

您可以改用接口:

public interface IRunnableSomething {
    void Run();
}

public class MyRunnableA :IRunnableSomething  
{
    public void Run() {
        // do stuff
    }
}

public class MyRunnableB :IRunnableSomething 
{
    public void Run() {
        // do stuff
    }
}

然后在你的主要课程中......

public override void Run(IRunnable runnable)
{
    runnable.Run();
}

调用它的示例:

myInstanceOfMainClass.Run(new MyRunnableA());

这似乎很合适,因为您已经知道index原始版本传递的内容。这只是将它从int基于移动到interface基于(最后也减少了代码)。

于 2013-08-24T01:17:24.747 回答
0

让我进一步解释一下。这是我正在尝试做的稍微详细一点的版本。您可以在这里看到我的抽象类具有指向派生类中正确方法的索引列表,并且您可以看到我在哪里加载类型并在 UI 中创建菜单项。我正在使用这个 ItemPointer 列表并传递 ItemPointers 以标记属性等。不知何故,这一切都感觉有点不对劲。

我希望整个事情都是可扩展的。我可能想添加一个 Class2、Class3 等都继承 BaseClass。我可能还想使用 BaseClass 创建插件。任何派生类都至少有一个可运行的方法,但可能会有很多。所以这里的 Class1 只是一个例子。这有助于解释我自己吗?请放轻松,我正在学习,这就是我在这里问的原因。

我在这里做的很糟糕吗?或者可以吗?或者,还有更好的方法?我想这是我的问题。如果有更好的方法,我真的很感激一个例子。非常感谢大家的帮助。非常感谢。

public abstract class BaseClass
{
    public List<ItemPointer> ItemPointers = new List<ItemPointer>();
    public abstract void Run(int index);
}



public class ItemPointer
{
    public int Index { get; set; }
    public string ClassType { get; set; }
    public string UIDescription { get; set; }
}



public class Class1 : BaseClass
{
    public Class1()
    {
        ItemPointers.Add(new ItemPointer { Index = 0, ClassType = this.GetType().Name,  UIDescription = "MethodA Description" });
        ItemPointers.Add(new ItemPointer { Index = 1, ClassType = this.GetType().Name,  UIDescription = "MethodB Description" });
    }

    public override void Run(int index)
    {            
        if (index == 0)
        {
            MethodA();
        }
        else if (index == 1)
        {
            MethodB();
        }
    }

    private void MethodA()
    {
        //do stuff
    }

    private void MethodB()
    {
        //do stuff
    }
}



public class UIForm
{
    private List<BaseClass> _baseClasses;

    //Formload events load all baseclass types (including plugins via reflection during form init etc. Then call loadUIitems

    private void LoadUIItems()
    {
        foreach (BaseClass bc in _baseClasses)
        {
            foreach (var p in bc.ItemPointers)
            {
                ToolStripMenuItem t = new ToolStripMenuItem(p.UIDescription);
                t.Click += new EventHandler(WorkerMenu_Click);
                t.Tag = p;
                actionsToolStripMenuItem.DropDownItems.Add(t);  
            }
        }
    }



    void WorkerMenu_Click(object sender, EventArgs e)
    {
        ToolStripMenuItem t = (ToolStripMenuItem)sender;
        ItemPointer p = (ItemPointer)t.Tag;

        foreach (BaseClass bc in _baseClasses)
        {
            if (bc.GetType().Name == p.ClassType)
            {
                bc.Run(p.Index);
            }
        }
    }
}
于 2013-08-24T13:16:29.683 回答
0

在你的位置上,我可能倾向于尝试做这样的事情:

void Main()
{
    var a = new Class1();
    var b = new Class2();

    try
    {           
        a.Run("Foo");
        b.Run("Bar", "Yoda");
        b.Run("Bat"); // throws exception
    }
    catch (Exception ex)
    {
        Console.WriteLine (ex.Message);
    }
}

class Base
{
    public void Run(string commandName, params object[] args)
    {
        var method = this.GetType().GetMethod(commandName);
        if(method != null)
            method.Invoke(this, args);
        else
            throw new Exception("the command " + commandName + " does not exist on " + this.GetType().Name);
    }
}

class Class1 : Base
{
    public void Foo()
    {
        Console.WriteLine ("I am foo");
    }
}

class Class2 : Base
{
    public void Bar(string str)
    {
        Console.WriteLine ("I am {0}", str);
    }
}

输出:

I am foo
I am Yoda
the command Bat does not exist on Class2
于 2013-08-24T13:35:59.690 回答