关于抽象的建议
本文关键字:抽象的 | 更新日期: 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