2017-08-29 69 views
2

我有Func<>具有泛型類作爲輸入參數。問題是如何將其轉換爲類似的Func,但是具有派生自前一個參數的類?現在下面的代碼在fu2中給我null。Func與通用類參數和鑄造

var fu = new Func<Envelope<Base>, object>(Simple); 
var fu2 = fu as Func<Envelope<Derived>, object>; 

public class Envelope<T> 
{ 
    public T Enveloped { get; set; } 
} 
public class Base 
{ 

} 
public class Derived: Base 
{ 

} 
+4

「FU2」似乎病命名,幸好C#編譯器有厚的皮膚。也就是說,你不能做你想做的事。 'Envelope '在任何意義上都不是'Envelope '的子類;這是一個無關的班級。 –

回答

2

Func<T, object>T逆變所以

var fu2 = fu as Func<Envelope<Derived>, object>; 

如果Envelope<Derived>Envelope<Base>亞型會成功。類是不變的,但你可以定義一個接口:

public interface IEnvelope<out T> 
{ 
    T Enveloped { get; } 
} 

,並有Envelope<T>實現它。那麼下面將編譯:

Func<IEnvelope<Base>, object> fu = null; 
Func<IEnvelope<Derived>, object> fu2 = fu; 
1

鑄造的一般表達式是不行的,因爲lambda表達式之間不存在協方差。

但是,你就可以說構建了一個新的Envelope<Base>的表達,並封裝包膜派生對象進去,就像這樣:

var fu = new Func<Envelope<Base>,object>(Simple); 
Func<Envelope<Derived>,object> fu2 = x => fu(new Envelope<Base> {Enveloped = x.Enveloped}); 

新的表達式調用funew Envelope<Base> {Enveloped = x.Enveloped}參數,這是一個信封由fu2表達式的參數構造的兼容類型。

Demo.