2013-08-24 126 views
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)。也许我需要将每个类的整数都作为方法映射。可能还需要为此集合添加一个字符串以保存菜单项的友好名称等。

您是否可以想到一种在保持尽可能多抽象的同时实现此类映射的方法?有没有更好的方法去解决这个问题,我目前的想法?

+1

问题似乎是“我发明的Windows消息循环.. 。 怎么办?” - 我建议跳过这些最初的痛苦版本,并直接使用强类型事件进行一些更新的事件机制... –

回答

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

+0

我想你忘了在每个类中包含':IRunnableSomething'。 –

+0

我确实。直接输入浏览器的危险! :) –

+0

感谢修复它的人。这样愚蠢的错误。 –

0

让我再解释一下。这是我想要做的稍微更详细的版本。你可以在这里看到我的抽象类有指向派生类中正确方法的索引列表,你可以看到我在哪里加载类型并在UI中创建菜单项。我正在使用这个ItemPointer列表并传递ItemPointers来标记属性等等。它总是感觉有点不对。

我希望整个事情是可扩展的。我可能想要添加一个继承BaseClass的Class2,Class3等。我可能也想使用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); 
      } 
     } 
    } 
} 
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