2014-11-13 18 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

相關問題