C# 委托方差和泛型

本文关键字:泛型 委托方 | 更新日期: 2023-09-27 17:56:19

在下面的代码中,我想使用一个具有更多派生参数的动作传递到使用基作为参数的动作中。 代码如下所示:

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 文档,它建议上述方法应该有效,因为我使用派生最少类(在本例中为基类)的参数将带有更多派生类参数的操作传递给操作,例如文档说明了以下内容:

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;
 }

}

我是否误解了某些内容,或者是否有

解决此问题的方法。

提前致谢

C# 委托方差和泛型

这从根本上来说是不安全的;你不能那样做。

Action<IDerivedContext>只能将IDerivedContext作为参数。 如果你能够将它转换为Action<IContext<int>>,你将能够用它实际上无法接受的其他一些IContext<int>实现来调用它。