如何将带有派生类型参数的委托转换为具有基类型参数的委托?

Tri*_*Gao 6 c#

考虑一下代码:

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);
Run Code Online (Sandbox Code Playgroud)

有没有办法让这种铸造工作?我知道在一般情况下,IGeneral无法投放到ISpecific.但在我的特殊情况下,我希望我能做到这样的事情:

 Func<IGeneral, String> generalFunc = new Func<IGeneral, String>(general => specificFunc(general as ISpecific));
Run Code Online (Sandbox Code Playgroud)

但是具有specificFuncas Object并且ISpecific只有via类型specificFuncAsObject.GetType()

Tim*_* S. 9

T(输入类型)in Func<T, TResult>逆变的,而不是协变的,所以这样的事情不是直接可能的.但是,您可以执行以下操作:

Func<ISpecific, String> specificFunc = specific => "Hey!";
Func<IGeneral, String> generalFunc = general => specificFunc((ISpecific)general);
Run Code Online (Sandbox Code Playgroud)

或者相反:

Func<IGeneral, String> generalFunc = general => "Hey!";
Func<ISpecific, String> specificFunc = generalFunc;
Run Code Online (Sandbox Code Playgroud)


Ant*_*ony 4

我认为这是不可能的,想想下面的情况:

class Base
{
}

class DerivedA : Base
{
}

class DerivedB : Base
{
}
Run Code Online (Sandbox Code Playgroud)

通过一些方法:

string DoSomething(DerivedA myDerived)
{
}
Run Code Online (Sandbox Code Playgroud)

然后,在某个地方你有代码:

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.
Run Code Online (Sandbox Code Playgroud)

您可以做的是使用实用函数通过强制转换(或as运算符,如果您愿意)进行转换:

Func<Base, string> Convert<T>(Func<T, string> function) where T : Base
{
return x => function(x as T);
}
Run Code Online (Sandbox Code Playgroud)

然后做类似的事情:

Func<DerivedA, string> functionA = DoSomething;
Func<Base, string> functionBase = Convert(functionA);
Run Code Online (Sandbox Code Playgroud)