2016-04-12 6 views
1

Ich versuche, einen Action to ist Constraint-Typ zu werfen. Warum C# kann es nicht werfen?Warum kann C# nicht implizit eine Aktion umwandeln? <T> Wobei T: BaseType zu Aktion <BaseType>

Wenn ich die Rückkehr zwingen gegossen ist null

private Action<BaseObject> MyAction { get; set; } 

//Cannot implicitly cast 
internal void SetMyAction<TModel>(Action<TModel> action) where TModel : BaseObject 
{ 
    MyAction = action; 
} 

//MyAction return null 
internal void SetMyAction<TModel>(Action<TModel> action) where TModel : BaseObject 
{ 
    MyAction = (Action<TModel>)action; 
} 

Antwort

3

Nicht jeder Action<TModel> ein Action<BaseObject> ist. Schauen wir uns ein konkretes Beispiel an: Action<string> und Action<object>.

Ein Action<object> Delegierter kann beliebigobject Referenz als Parameter nehmen. Es ist absolut gültig, action(new object()) zu schreiben.

Jetzt denken Sie an eine Action<string> - es kann nur nehmen Sie eine string Referenz. Sie erwarten offensichtlich, dass der folgende Code kompiliert wird - wie würden Sie erwarten, dass er sich zur Ausführungszeit verhält?

Action<string> printLength = text => Console.WriteLine(text.Length); 
Action<object> action = printLength; // This isn't actually valid 
action(new object()); 

Grundsätzlich ist Action<T>kontra in T, nicht kovarianten. Also ist eine implizite Umwandlung von Action<object> zu Action<string>, aber nicht umgekehrt.

Anwendung, die zu Ihrem speziellen Fall vorstellen, dass ich hatte:

Action<DerivedObject1> x = do1 => Console.WriteLine(do1.SomeProperty); 
SetMyAction<DerivedObject1>(x); 

// Presumably there's *something* to invoke the action... 
InvokeMyAction(new DerivedObject2()); 

Was möchten Sie passieren erwarten?