2010-12-17 10 views

Odpowiedz

16

C# ma bardzo ograniczone wsparcie dla „strukturalnego” pisania. W szczególności nie można rzutować z jednego typu delegata na inny po prostu, ponieważ ich deklaracje są podobne.

Od specyfikacji języka:

rodzaje powierzać C# to nazwa odpowiednik, nie strukturalnie równoważne. W szczególności dwa różne typy delegatów, które mają same listy parametrów i zwracają typ , są traktowane jako różne typy delegatów: .

Wypróbuj jedną z:

// C# 2, 3, 4 (C# 1 doesn't come into it because of generics) 
BinaryOperation b1 = new BinaryOperation(addThem); 

// C# 3, 4 
BinaryOperation b1 = (x, y) => addThem(x, y); 
var b1 = new BinaryOperation(addThem); 
+0

Genialny! Dziękuję Ci! (... Musisz poczekać 11 minut, aby zaznaczyć swoją odpowiedź jako odpowiedź ...). – Hobbes

+12

Powodem typowania niestrukturalnego jest to, że definicja delegata może mieć semantykę. Nie powinno być możliwości przypisania "Func" do "SecureFunc", "PureFunc" lub "NoSideEffectsFunc" lub cokolwiek innego. W praktyce nikt właściwie nie robi delegatów, które mają semantykę; gdybyśmy musieli to robić od nowa, delegaci byliby prawdopodobnie bardziej strukturalnie wpisani. –

+0

@Eric Lippert: To interesujący punkt. Jaki jest twój pogląd na to, dlaczego istnieje tylu "zduplikowanych" typów delegatów o tej samej "strukturze" w BCL, takich jak Action, ThreadStart, MethodInvoker? – Ani

7

Oto podobne pytanie: dlaczego nie to skompilować?

// declared somewhere 
struct Foo { 
    public int x; 
    public int y; 
} 

struct Bar { 
    public int x; 
    public int y; 
} 

// ... in a method body 
Foo item = new Foo { x = 1, y = 2 }; 

Bar b1 = item; // doesn't compile, and casting doesn't compile 
Bar b2 = new Bar { x = 1, y = 2 }; // compiles! 

W tym przypadku wydaje się nieco bardziej naturalne, że obsada nie działa, ale z tego samego powodu.

Powiązane problemy