Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-有人能告诉我为什么以及在哪里使用代理吗?_C#_Delegates - Fatal编程技术网

C#-有人能告诉我为什么以及在哪里使用代理吗?

C#-有人能告诉我为什么以及在哪里使用代理吗?,c#,delegates,C#,Delegates,我想我理解C#中委托作为方法指针的概念,但是我找不到任何好的例子来说明在哪里使用它们是一个好主意。哪些示例对于学员而言明显更优雅/更好,或者无法使用其他方法解决 我主要使用用于简单异步编程的。正在使用委托开始启动方法。。。如果你想开火然后忘记,这个方法真的很简单 当接口不可用时,委托也可以像接口一样使用。例如,从COM类、外部.Net类等调用方法。delgates将解决其他方法无法解决的问题,但它们提供了一个更优雅的解决方案 对于委托,只要具有所需参数,就可以使用任何函数 另一种方法通常是在程序

我想我理解C#中委托作为方法指针的概念,但是我找不到任何好的例子来说明在哪里使用它们是一个好主意。哪些示例对于学员而言明显更优雅/更好,或者无法使用其他方法解决

我主要使用用于简单异步编程的。正在使用委托开始启动方法。。。如果你想开火然后忘记,这个方法真的很简单


当接口不可用时,委托也可以像接口一样使用。例如,从COM类、外部.Net类等调用方法。

delgates将解决其他方法无法解决的问题,但它们提供了一个更优雅的解决方案

对于委托,只要具有所需参数,就可以使用任何函数


另一种方法通常是在程序中使用一种定制的事件系统,为.NET 1.0代理中的bug创建额外的工作和更多的区域:

this.myButton.Click += new EventHandler(this.MyMethod);
this.myOtherButton.Click += delegate {
    var res = PerformSomeAction();
    if(res > 5)
        PerformSomeOtherAction();
};
.NET 2.0代表:

this.myButton.Click += new EventHandler(this.MyMethod);
this.myOtherButton.Click += delegate {
    var res = PerformSomeAction();
    if(res > 5)
        PerformSomeOtherAction();
};
它们似乎很有用。那么:

new Thread(new ThreadStart(delegate {
    // do some worker-thread processing
})).Start();

事件是最明显的例子。比较观察者模式在Java(接口)和C#(委托)中的实现方式


此外,许多新的C#3功能(例如lambda表达式)都基于委托,并进一步简化了它们的使用。

例如在多线程应用程序中。如果希望多个线程使用某些控件,则应使用委托。抱歉,代码是VisualBasic

首先声明一个委托

Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean)
编写一个函数,从多个线程启用/禁用按钮

Private Sub enable_button(ByVal enabled As Boolean)
    If Me.ButtonConnect.InvokeRequired Then

        Dim del As New ButtonInvoke(AddressOf enable_button)
        Me.ButtonConnect.Invoke(del, New Object() {enabled})
    Else
        ButtonConnect.Enabled = enabled
    End If

End Sub

我一直在LINQ中使用它们,尤其是lambda表达式,以提供一个函数来计算条件或返回选择。还可以使用它们提供一个功能,用于比较两个项目进行排序。后者对于默认排序可能合适也可能不合适的泛型集合非常重要

   var query = collection.Where( c => c.Kind == ChosenKind )
                         .Select( c => new { Name = c.Name, Value = c.Value } )
                         .OrderBy( (a,b) => a.Name.CompareTo( b.Name ) );

委托的好处之一是异步执行


当您异步调用一个方法时,您不知道它将在何时完成执行,因此您需要向该方法传递一个委托,该委托指向在第一个方法完成执行时将调用的另一个方法。在第二种方法中,您可以编写一些代码,通知您执行已完成。

其他一些关于异步世界的注释。。。但我还是要评论一下,因为我最喜欢的“味道”是这样做的:

ThreadPool.QueueUserWorkItem(delegate
{
    // This code will run on it's own thread!
});
此外,委托的一个重要原因是“回调”。假设我做了一些功能(异步),您希望我调用一些方法(比如“AlertWhenDone”)。。。您可以按如下方式向方法传递“委托”:

TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone);

委托在事件中的角色(如果您使用过winforms或asp.net,您可能会很熟悉)之外,还有助于使类更灵活(例如在LINQ中使用它们的方式)

“发现”事物的灵活性相当普遍。你有很多东西,你想提供一种找到东西的方法。现在,您可以允许调用者提供算法,以便他们可以按照自己认为合适的方式搜索您的集合,而不是猜测某人可能想要查找的每种方式

下面是一个简单的代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegates
{
    class Program
    {
        static void Main(string[] args)
        {
            Collection coll = new Collection(5);
            coll[0] = "This";
            coll[1] = "is";
            coll[2] = "a";
            coll[3] = "test";

            var result = coll.Find(x => x == "is");

            Console.WriteLine(result);

            result = coll.Find(x => x.StartsWith("te"));

            Console.WriteLine(result);

    }

}

public class Collection
{
    string[] _Items;

    public delegate bool FindDelegate(string FindParam);

    public Collection(int Size)
    {
        _Items = new string[Size];

    }

    public string this[int i]
    {
        get { return _Items[i]; }
        set { _Items[i] = value; }
    }

    public string Find(FindDelegate findDelegate)
    {
        foreach (string s in _Items)
        {
            if (findDelegate(s))
                return s;
        }
        return null;
    }

}
}
输出


测试

你所说的代表到底是什么意思?以下是它们的两种使用方式:

void Foo(Func<int, string> f) {
 //do stuff
 string s = f(42);
 // do more stuff
}
void Foo(函数f){
//做事
字符串s=f(42);
//多做事
}

void Bar(){
Func f=委托(i){返回i.ToString();}
//做事
字符串s=f(42);
//多做事
}
第二种方法的要点是,您可以动态地以委托的形式声明新函数。这在很大程度上可以被lambda表达式所取代,并且在任何时候,只要有一小段逻辑想要1)传递给另一个函数,或者2)只是重复执行,它都很有用。LINQ就是一个很好的例子。每个LINQ函数都将lambda表达式作为其参数,指定行为。例如,如果您有一个
列表l
,那么
l.Select(x=>(x.ToString())
将对列表中的每个元素调用ToString()。我编写的lambda表达式作为委托实现

第一种情况显示了如何实现Select。您可以将委托作为参数,然后在需要时调用它。这允许调用方自定义函数的行为。使用Select()再举一个例子,函数本身保证您传递给它的委托将在列表中的每个元素上被调用,并返回每个元素的输出。该委托的实际作用取决于您。这使它成为一个非常灵活和通用的函数


当然,它们也用于订阅事件。简言之,委托允许您引用函数,在函数调用中使用它们作为参数,将它们分配给变量以及您喜欢做的任何事情。

从技术上讲,委托是一种引用类型,用于封装具有特定签名和返回类型的方法

在处理对数据库的外部调用时,使用委托是否有优势

例如,您可以编写以下代码:

static void Main(string[] args) {

           DatabaseCode("test");

}

public void DatabaseCode(string arg) {

           .... code here ...

}
在代码B中需要改进:

static void Main(string[] args) {

           DatabaseCodeDelegate slave = DatabaseCode;
           slave ("test");

}

public void DatabaseCode(string arg) {

           .... code here ...

}
public delegate void DatabaseCodeDelegate(string arg);

这似乎是主观的,但这是一个存在强烈冲突的观点的领域?

天哪,我差不多一年前就提出了这个问题,现在很难想象在代表/lambda表达之前的生活!我不得不说,这里的答案仍然是网络上最好的例子。这就是SO的力量。这简直太棒了理解