首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解委托对比有用性

理解委托对比有用性
EN

Stack Overflow用户
提问于 2013-09-12 19:43:00
回答 3查看 1.9K关注 0票数 8

因此,我有一位代表被定义为:

代码语言:javascript
复制
public delegate void MyDelegate<T>(T myParameter);

Resharper建议我应该将T反变体如下所示:

代码语言:javascript
复制
public delegate void MyDelegate<in T>(T myParameter);

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

代码语言:javascript
复制
public delegate void MyDelegate<T>(T myParameter);

我无法用它创造

代码语言:javascript
复制
public delegate void MyDelegate<in T>(T myParameter);
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-12 20:19:36

下面是一个实例,如果删除逆反式in标记,它将不会编译:

代码语言:javascript
复制
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); };
}

当然,有些人为的,但至少应该给你一个想法,什么样的事情,你不能没有它。

特别要考虑的是,如果AddLabelClickCallbackAddButtonClickCallback是库函数,Callback是库代表。如果它是在没有逆反关系的情况下定义的,那么您必须定义不同的委托-- showButtonTextshowLabelText --即使您只希望他们做同样的事情。

票数 6
EN

Stack Overflow用户

发布于 2013-09-12 19:49:04

泛型上的in关键字允许隐式转换。基本上,您可以向您的委托分配较少的派生委托类型..。并不总是有用的,在这里阅读更多的信息。

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

例如,来自MSDN的文章:

代码语言:javascript
复制
// 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类型,但如果在Button类中未定义隐式转换为Button类型以允许Control变为Button,则可能会出现异常。

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

票数 4
EN

Stack Overflow用户

发布于 2013-09-12 19:52:43

在堆栈溢出:Covariance and contravariance in programming languages上已经多次问到这个问题了。

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

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18773067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档