2014-11-13 28 views
-2

我想了解是否/何时在代码中使用委托和接口。结构非常简单。主类初始化窗口形式:C#代表和接口如何在此示例中扮演角色

class MainClass 
{ 
    public static void Main() 
    { 
     InputForm InputForm1 = new InputForm(); 
     InputForm1.ShowDialog(); // show interface to prompt user 
    } 
} 

和窗体的类有一个按钮,几个方法:

public partial class InputForm : Form 
{ 
    public InputForm() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // do some calculation and then create a dictionary of items 

     for (int n = 1; n <= dict.Count; n++) // loop through items 
     { 

      dict[n].calculatedLength = theLength.calcLength(arg1, arg2, dict[n].speed); 

     } 
    } 
} 

当单击该按钮,程序会进行一些计算(调用方法在相同的类InputForm中)并将结果保存到字典(dict)中。每个元素都是一种动物,我拥有一些存储在字典中的属性(例如,在“狗”的关键字下,我拥有狗的平均体重,平均速度等)。 使用速度和两个默认参数(arg1表示小时数,arg2表示分钟数)我必须调用类LengthClass的方法才能获得特定动物所覆盖的估计长度arg1小时和arg2分钟。 的LengthClass是这样的:

class LengthClass 
{ 
    static double calcLength(double arg1, double arg2, double speed) 
    { 
     // do some calculation 
     return x; 
    } 
} 

现在的问题:有没有在这个例子中使用委托和接口的空间?你能告诉我如何最好地做到这一点,这样做有什么优点/缺点,而不是像我在做的那样直接调用calcLength方法?

+0

您具体询问代表和接口,但是考虑问题的上下文我怀疑动机更多的是在单独的线程上获取煅烧以保持表单响应?我的怀疑是否正确? (代表和接口不直接这样做) –

+0

@Stewart_R我想看看我能否更好地设计代码。但是会出现一些新手问题:1)我的LengthClass可以实现一个接口(但是如何最好地做到这一点,这是一个方便的选择?)2)我的方法calcLength()可以委托(但如何最好地做到这一点,它是一个方便的选择?)。 – mickG

+1

@Jon - 我不认为这是落后的。我们经常获得新技术,并想知道如何应用它们。这听起来像OP只是试图学习何时应用代表和/或接口。 – Enigmativity

回答

0

编辑:我包括Microsoft guideline


微软方针

双方代表和接口,使类的设计师来单独类型声明和实现。给定的接口可以被任何类或结构体继承和实现。只要该方法符合代理的方法签名,就可以为任何类上的方法创建委托。接口引用或委托可以由不知道实现接口或委托方法的类的对象使用。鉴于这些相似之处,类应用程序何时应该使用委托,何时应该使用接口?

在下列情况下使用委托:用于

  • 的三项赛的设计模式。
  • 需要封装一个静态方法。
  • 调用者不需要访问实现该方法的对象上的其他属性,方法或接口。
  • 简单的组成是期望的。
  • 一个类可能需要该方法的多个实现。

使用在下列情况下的接口:

  • 有一组相关的方法可以被调用。
  • 一个类只需要该方法的一个实现。
  • 使用该接口的类将要将该接口强制转换为其他接口或类类型。
  • 正在实施的方法链接到类的类型或标识:例如,比较方法。

原来的答案(我觉得)

Interfacesdelegates作了使事情变得更容易,当两个类具有相同的礼仪/行为。

我认为,如果你有类似的东西

private void Button(object sender, EventArgs e) 
{ 
    List<IAnimal> animals = Farm.GetAnimals(); 
    foreach(IAnimal animal in animals) 
    { 
     dict[animal.name] = LeghtClass.CalculateLenght(animal); 
     //dict[animal.name] = animal.CalculateOwnLenght(); //using a method in the interface 
    } 
} 

你就不必担心传递其参数(wichh将重构时,帮助你)的方法。

interface IAnimal 
{ 
    double Hours; 
    double Minutes; 
    double GrowSpeed; 
    //void CalculateOwnLenght(); 
} 

和你lenght类将计算的话这样的:

class LengthClass 
{ 
    static double calcLength(IAnimal animal) 
    { 
     return (animal.Hours + animal.Minutes/60) * animal.GrowSpeed; 
    } 
} 

我想不出代表们如何帮助你,除非你做这样的事情:

foreach(var animal in animals) 
{ 
    delegate = animal.CalculateOwnLeght; 
    dict[animal.name] = delegate(); 
} 

好吧,我已经显示了一些代码,没有说什么。

如果你在多个地方使用它们,我认为接口是有用的,否则它可能会变得混乱 - 你只是在使用接口的时候重复自己。

我个人认为你的方式是错误的,但我读过人们说静态是不好的做法,没有证明为什么我能够理解,我记得的一件事是,它容易混淆,并使用更多资源。

我会使用委托,当我必须指向一些方法,但我不知道直到代码运行的对象(他们没有用于这种情况下,我认为)。

delegate void Cry(); 

... 

cat = new Cat(); dog = new Dog(); 

... 

foreach(var animal in animals) 
{ 
    if (animal is Cat) 
    { 
     Cry = cat.meow; 
    } 
    else if (animal is Dog) 
    { 
     Cry = dog.bark; 
    } 
    else {...} 

    if (animal.isInPain) 
    { 
     Cry(); 
    } 
} 
+0

谢谢你的答案,但我不知道如何应用这个。根据我的例子,你可以更具体一些吗?我可能会在将来添加更多可以实现与LengthClass相同的接口的类,但这里要指出的是如何帮助获得更好的代码。另外,如何使用委托给方法calcLength()和LengthClass中的其他方法可以使代码更好,只需在需要时直接调用方法? – mickG

+0

看看[这](http://stackoverflow.com/a/2020501/3178998)和[这](http://stackoverflow.com/a/2019564/3178998),他们都比我更好的答案。我还发现[关于代表这个很好的解释](http://stackoverflow.com/a/17317903/3178998)和这个[微软指南](http://msdn.microsoft.com/en-us/library/ms173173% 28V = VS.90%29.aspx) – MVCDS