使用泛型类参数和强制转换的Func

时间:2017-08-29 19:41:08

标签: c# generics casting

我有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
{

}

2 个答案:

答案 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表达式的参数构造的兼容类型的包络。

Demo.