C# 具有泛型类参数和类型转换的Func

C# 具有泛型类参数和类型转换的Func,c#,generics,casting,C#,Generics,Casting,我有Func,它的输入参数是泛型类。问题是如何将其转换为类似的Func,但使用的类的参数派生自上一个?现在下面的代码在fu2中为空 var fu = new Func<Envelope<Base>, object>(Simple); var fu2 = fu as Func<Envelope<Derived>, object>; public class Envelope<T> { public T Enveloped { g

我有
Func
,它的输入参数是泛型类。问题是如何将其转换为类似的Func,但使用的类的参数派生自上一个?现在下面的代码在fu2中为空

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
{

}
var fu=新函数(简单);
var fu2=fu作为Func;
公共类信封
{
公共T包络{get;set;}
}
公共阶级基础
{
}
派生的公共类:基
{
}

强制转换泛型表达式不起作用,因为lambda表达式之间没有协方差

但是,您可以创建一个表达式来构造一个新的
信封
,并将信封衍生对象包装到其中,如下所示:

var fu = new Func<Envelope<Base>,object>(Simple);
Func<Envelope<Derived>,object> fu2 = x => fu(new Envelope<Base> {Enveloped = x.Enveloped});
var fu=新函数(简单);
Func fu2=x=>fu(新信封{Enveloped=x.Enveloped});
新表达式使用
新信封{Enveloped=x.Enveloped}
参数调用
fu
,该参数是由
fu2
表达式的参数构造的兼容类型的信封

Func
T
so中是逆变的

var fu2 = fu as Func<Envelope<Derived>, object>;
var fu2=fu作为Func;
如果
信封
信封
的子类型,则将成功。类是不变的,但您可以定义一个接口:

public interface IEnvelope<out T>
{
    T Enveloped { get; }
}
公共接口开发
{
T包络{get;}
}
并让
信封
实现它。然后将编译以下内容:

Func<IEnvelope<Base>, object> fu = null;
Func<IEnvelope<Derived>, object> fu2 = fu;
Func-fu=null;
Func fu2=fu;
“fu2”似乎名字不好,但幸运的是C#编译器有厚厚的外壳。也就是说,你不能做你想做的事<代码>信封在任何意义上都不是
信封
的子类;这是一门无关的课。