关于抽象的建议

本文关键字:抽象的 | 更新日期: 2023-09-27 18:28:47

我正在编写一些代码,其中我有一个抽象类,该类具有一些核心属性和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调用,例如单击菜单。所以我可能有一个班1和一个班2。Class1可能有3个方法,所以我可以调用run(0)。。。在上面运行(2)。Class2可能只有一个内部方法,所以我只调用run(0)。也许我需要保留每个类的int集合,作为方法的映射。可能还需要向这个集合添加一个字符串来保存菜单项等的友好名称。

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

关于抽象的建议

单向:

你可以使用一个接口:

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(最终也减少了代码)。

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

我希望整件事是可扩展的。我可能想添加一个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);
            }
        }
    }
}

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

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