2013-08-22 20 views
4

我的問題有點類似於此:How to convert an action to a defined delegate of the same signature?代表們同樣簽名

爲什麼沒有與相同的簽名代表之間沒有隱含的皈依。例如,代碼:

class Program 
{ 
    private delegate void Foo1(int x); 
    private delegate void Foo2(int x); 


    static void Main(string[] args) 
    { 
     Foo1 foo1 = Console.WriteLine; 
     Foo2 foo2 = Console.WriteLine; 

     Call(foo1); 

     Call2(foo2); 
    } 

    static void Call(Action<int> action) 
    { 
     action(10); 
    } 

    static void Call2(Foo1 action) 
    { 
     action(10); 
    } 
} 

它不會編譯,因爲there isn't implicit convertion from Action<int> to Foo1. 但normaly這是同樣的事情。所以這意味着這個名字是別名,而不是真實的名字。所以我認爲這是一個好主意,可以像別名一樣思考它。所以在這種情況下,我們有一個delegate, that get one int value and returns nothing的3個別名。而這些代表完全可以互換。但我們沒有它。所以問題是:爲什麼?通過簽名是同樣的事情,並沒有任何實現,所以具有相同簽名的代表是一個和許多別名相同...

它是C#缺陷還是有原因呢?至於我,我沒有看到任何。

+4

我不認爲這是一個缺陷,個人,但這*爲*爲什麼我生氣的時候人們定義他們自己的代表而不是僅僅使用'Action' /'Func'。 – Servy

回答

2

有出於同樣的原因是有這兩種類型之間的隱式轉換這兩個代表之間的隱式轉換:

public sealed class Foo1 
{ 
    public string Value { get; set; } 
} 

public sealed class Foo2 
{ 
    public string Value { get; set; } 
} 

僅僅因爲兩個類具有相同的字段,並不意味着你應該能夠把一個人看作是另一個人。同樣的邏輯適用於代表(也是類型,介意你)。

在創建該類型時應用了語義。如果有人創建了Foo1,他們希望它是Foo1,而不是Foo2。如果他們不願意使用Foo1(其中Foo2是預期的),那麼即使類型看起來相似,這也是一個大紅旗,這兩種類型之間存在語義差異。如果程序員知道編譯器沒有的東西,他們可以使用某種顯式轉換來表明他們知道他們在做什麼。

(前項是故意寫同樣適用於你的委託和類我上面提供。)

+0

編號類可以是局部的,可以繼承等。例如,我有行動。我不想寫關於它的簡單/ XML註釋,我可以簡單地寫'MySpecialDelegate = Action'這樣的東西,它只是一個自我記錄的代碼。對於類,它可能是一個很好的功能,但對他們來說,它不會被頻繁使用,因爲幾乎所有這兩個類**都不是一樣的**,而是代表 - 是。當我寫'使用MyAlarmTimer = System.Timers.Timer'時,我並不是指'大紅旗',我只是想簡化一些代碼並解釋它沒有意見 –

+1

爲什麼我不能在這裏做同樣的 - 我不知道。就像在這種情況下,它只是一個別名,對於運行代碼來說,它們之間沒有區別。如果.Net中的所有代表都可以自動轉換爲Action/Func - 這將非常好 –

+0

@AlexJoukovsky不是所有具有相同簽名的方法都是相同的。該方法的語義含義很可能對它更有幫助。 *您不可以使用不同的代表來附加語義,但這並不意味着沒有人會這樣做,或者語言設計者認爲不應該這樣做。至於這些課程是不完整的,那並不是真的有意義。一旦它們被編譯器編譯,它只是一個類定義。至於遺傳,它們可以被封存;如果它讓你感覺好一些,我會在我的例子中加上。 – Servy