C# 委托对冲(参数兼容性)

C# 委托对冲(参数兼容性),c#,c#-5.0,C#,C# 5.0,简而言之,我在看C#5文本中有关委托参数兼容性的部分。上面说 调用方法时,可以提供比该方法的参数具有更多特定类型的参数。这是普通的多态行为。出于完全相同的原因,委托可以具有比其方法目标更具体的参数类型。这叫做逆变 这一段直到最后一句都有意义。为什么是逆变,也就是说,这里的投影是逆变的 下面是附带的示例 delegate void StringAction (string s); class Test { static void Main() { StringAc

简而言之,我在看
C#5
文本中有关委托参数兼容性的部分。上面说

调用方法时,可以提供比该方法的参数具有更多特定类型的参数。这是普通的多态行为。出于完全相同的原因,委托可以具有比其方法目标更具体的参数类型。这叫做逆变

这一段直到最后一句都有意义。为什么是逆变,也就是说,这里的投影是逆变的

下面是附带的示例

delegate void StringAction (string s);

class Test
{
    static void Main()
    {
        StringAction sa = new StringAction (ActOnObject);
        sa ("hello");
    }

    static void ActOnObject (object o)
    {
        Console.WriteLine (o); // hello
    }
}

object
(函数
ActionObject
的参数)到为委托声明的类型(
string
)的投影是反向的

这是允许的,因为通过向它传递一个字符串(由于委托签名,您必须传递该字符串),可以保证您将拥有一个
对象
(分配的函数将使用该对象),因此一切都很好且安全

正如你所知,在这种情况下,“普通多态性”实际上被称为协方差


有关更多详细信息,请参阅

函数类型在参数类型中是逆变的。在您的示例中

delegate void ObjectAction(object o);
是的一个子类型

delegate void StringAction(string s);
由于
ObjectAction
可以在使用
StringAction
的任何地方使用,因为如果调用方传入
string
参数,该参数也必须是
object
类型


object
string
的超类型,但
ObjectAction
StringAction
的子类型;子类型朝相反的方向发展。这就是为什么它被称为逆变。因为函数子类型的变化方向与参数子类型的变化方向相反。

我感到困惑,因为当您使用
string
参数调用
StringAction
时,该参数在到达目标方法时会向上转换为
object
。所以我们从
string
转到
object
,而不是反过来。你能详细说明一下吗?@async你说得很对。在这种情况下,它是逆变的,主要是因为它在参数上,而参数不允许是协变的(特别是在接口上)。它在界面上的运行方向也更为明显。还有一个例子和你贴的很相似。