在下面的代码中,我想使用一个具有更多派生参数的动作传递给一个使用base作为参数的动作。代码如下所示:
public interface IContext<T>
{
}
public interface IWorkflow<T>
{
void Do(Action<IContext<T>> lambda);
}
public interface IDerivedContext : IContext<int>
{
}
public interface IDerivedWorkflow : IWorkflow<int>
{
void Do(Action<IDerivedContext> lambda);
}
public class Workflow<T> : IWorkflow<T>
{
public void Do(Action<IContext<T>> lambda)
{
Console.WriteLine("in Do(Action<IContext<T>>");
}
}
public class DerivedContext : IContext<int>
{
}
public class DerivedWorkflow : Workflow<int>, IDerivedWorkflow
{
public void Do(Action<IDerivedContext> lambda)
{
base.Do(lambda); // Compiler error:
}
}
如果我投这一行:
base.Do(lambda);
像这样:
base.Do((Action<IContext<int>>)lambda);
编译器接受转换,但代码在运行时因InvalidCastException而失败。
基于MSDN文档,它建议上面的内容应该有效,因为我将一个带有更多派生类参数的Action传递给一个Action,它使用一个派生类最少的参数(在本例中是基类)例如,文档说明了以下内容:
static void AddToContacts(Person person)
{
// This method adds a Person object
// to a contact list.
}
static void Test()
{
// Create an instance of the delegate without using variance.
Action<Person> addPersonToContacts = AddToContacts;
// The Action delegate expects
// a method that has an Employee parameter,
// but you can assign it a method that has a Person parameter
// because Employee derives from Person.
Action<Employee> addEmployeeToContacts = AddToContacts;
}
}
我是否误解了某些问题或是否有解决此问题的方法。
提前致谢
答案 0 :(得分:0)
这根本不安全;你不能这样做。
Action<IDerivedContext>
只能将IDerivedContext
作为参数。如果您能够将其转换为Action<IContext<int>>
,则可以使用其他IContext<int>
实施方式将其调用,但它实际上无法接受。