8

所以我有一个代表定义为:

public delegate void MyDelegate<T>(T myParameter);

Resharper 建议我应该T按如下方式进行逆变:

public delegate void MyDelegate<in T>(T myParameter);

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

public delegate void MyDelegate<T>(T myParameter);

我不能用

public delegate void MyDelegate<in T>(T myParameter);
4

3 回答 3

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

有点做作,当然,但至少应该让您了解没有它就不能做的事情。

尤其要考虑 ifAddLabelClickCallbackAddButtonClickCallbackwere 库函数并且Callback是库委托。如果它是在没有逆变的情况下定义的,则您必须定义不同的委托showButtonTextshowLabelText即使您只是希望它们做同样的事情。

于 2013-09-12T20:19:36.527 回答
4

generic 上的in关键字允许进行隐式转换。基本上,您可以将较少派生的委托类型分配给您的委托......并不总是有用,请阅读此处了解更多信息。

http://msdn.microsoft.com/en-us/library/dd469484.aspx

示例,来自 MSDN 文章:

// Contravariant delegate. 
public delegate void DContravariant<in A>(A argument);

// Methods that match the delegate signature. 
public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }

public void Test()
{
    // Instantiating the delegates with the methods.
    DContravariant<Control> dControl = SampleControl;
    DContravariant<Button> dButton = SampleButton;

    // You can assign dControl to dButton 
    // because the DContravariant delegate is contravariant.
    dButton = dControl;

    // Invoke the delegate.
    dButton(new Button()); 
}

在该示例中,Control将隐式转换为类型,但如果未在类中定义隐式转换为类型以允许成为Button,则可能会发生异常。ButtonButtonControlButton

更多关于隐式转换定义:http: //msdn.microsoft.com/en-us/library/z5z9kes2.aspx

于 2013-09-12T19:49:04.393 回答
1

这个问题在stackoverflow上被问过很多次: 编程语言中的协变和逆变

我建议你通过:http: //blogs.msdn.com/b/ericlippert/archive/2007/10/22/covariance-and-contravariance-in-c-part-four-real-delegate-variance.aspx

Covariance and Contravariance in C#, Part One
Covariance and Contravariance in C#, Part Two: Array Covariance
Covariance and Contravariance in C#, Part Three: Method Group Conversion Variance
Covariance and Contravariance in C#, Part Four: Real Delegate Variance
Covariance and Contravariance In C#, Part Five: Higher Order Functions Hurt My Brain
Covariance and Contravariance in C#, Part Six: Interface Variance
Covariance and Contravariance in C# Part Seven: Why Do We Need A Syntax At All?
Covariance and Contravariance in C#, Part Eight: Syntax Options
Covariance and Contravariance in C#, Part Nine: Breaking Changes
Covariance and Contravariance in C#, Part Ten: Dealing With Ambiguity
于 2013-09-12T19:52:43.350 回答