考虑代码:
public interface IGeneral {}
public interface ISpecific : IGeneral {}
public Func<IGeneral, String> Cast(Object specificFuncAsObject) {
var generalFunc = specificFuncAsObject as Func<IGeneral, String>;
Assert.IsNotNull(generalFunc); // <--- casting didn't work
return generalFunc;
}
Func<ISpecific, String> specificFunc = specific => "Hey!";
var generalFunc = Cast(specificFunc);
有没有办法让这种铸造工作?我知道在一般情况下,IGeneral无法投放到ISpecific。但在我的特殊情况下,我希望我能做到这样的事情:
Func<IGeneral, String> generalFunc = new Func<IGeneral, String>(general => specificFunc(general as ISpecific));
但将specificFunc
作为对象并ISpecific
仅通过specificFuncAsObject.GetType()
输入
答案 0 :(得分:9)
Func<T, TResult>
中的 T
(输入类型)是contravariant, not covariant,所以这样的事情不可能直接发生。但是,您可以执行以下操作:
Func<ISpecific, String> specificFunc = specific => "Hey!";
Func<IGeneral, String> generalFunc = general => specificFunc((ISpecific)general);
反之亦然:
Func<IGeneral, String> generalFunc = general => "Hey!";
Func<ISpecific, String> specificFunc = generalFunc;
答案 1 :(得分:4)
我认为这是不可能的,请考虑以下情况:
class Base
{
}
class DerivedA : Base
{
}
class DerivedB : Base
{
}
使用一些方法:
string DoSomething(DerivedA myDerived)
{
}
然后,在某处你有代码:
Func<DerivedA, string> functionA = DoSomething;
// Let's assume this cast is possible...
Func<Base, string> functionBase = (Func<BaseB, string>) functionA;
// At this point, the signature of the function that functionBase is assigned to
// is actually `string DoSomething(DerivedA myDerived)`
functionB(new DerivedB());
// If the cast is allowed, then passing a DerivedB should be allowed, but this makes
// absolutely no sense because the function is expecting a DerivedA.
如果您愿意,可以使用效用函数转换为强制转换(或as
运算符):
Func<Base, string> Convert<T>(Func<T, string> function) where T : Base
{
return x => function(x as T);
}
然后执行以下操作:
Func<DerivedA, string> functionA = DoSomething;
Func<Base, string> functionBase = Convert(functionA);