了解代表逆向有用性

Axi*_*xus 8 c# generics delegates variance

所以我有一个委托定义为:

public delegate void MyDelegate<T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)

Resharper建议我应该T如下逆变:

public delegate void MyDelegate<in T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)

现在,我很难理解这有什么用处?我知道它阻止我制作T一个返回类型,但T除此之外,通过制作逆变会得到什么有用的约束?也就是说,当需要将委托与实例一起使用时,我可以创建哪些实例

public delegate void MyDelegate<T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)

我无法创造

public delegate void MyDelegate<in T>(T myParameter);
Run Code Online (Sandbox Code Playgroud)

Dax*_*ohl 6

这是一个实例,如果你删除逆变in标记,它将无法编译:

delegate void Callback<in T>(T t);

public Form1()
{
    InitializeComponent();
    Callback<Control> showText = control => MessageBox.Show(control.Text);
    var button = new Button();
    AddButtonClickCallback(button, showText);
    var label = new Label();
    AddLabelClickCallback(label, showText);
}

static void AddButtonClickCallback(Button button, Callback<Button> callback)
{
    button.Click += delegate { callback(button); };
}

static void AddLabelClickCallback(Label label, Callback<Label> callback)
{
    label.Click += delegate { callback(label); };
}
Run Code Online (Sandbox Code Playgroud)

确实有点做作,但至少应该让你知道没有它你不能做的事情.

特别是考虑是否AddLabelClickCallbackAddButtonClickCallback库函数,并且Callback是图书馆代表.如果它是在没有逆变的情况下定义的,那么你必须定义不同的代理showButtonText,showLabelText即使你只是希望它们做同样的事情.

  • @YasmaniLlanes优秀的问题.虽然你的建议在理论上是有道理的,但Eric Lippert在他的博客中提供了几个实用的理由来证明`in`和`out`标记的必要性:http://blogs.msdn.com/b/ericlippert/archive/2007/10 /29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx (2认同)