我有Func<>
通用类作为输入参数。问题是如何将它转换为类似的Func但是具有从前面派生的参数的类?现在下面的代码在fu2中给我null。
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
{
}
答案 0 :(得分: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 :(得分: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});
新表达式使用fu
参数调用new Envelope<Base> {Enveloped = x.Enveloped}
,该参数是从fu2
表达式的参数构造的兼容类型的包络。