C# - 有人能告诉我为什么以及在哪里使用代表? [重复]

时间:2022-02-22 17:17:52

This question already has an answer here:

这个问题在这里已有答案:

I think I understand the concept of a delegate in C# as a pointer to a method, but I cant find any good examples of where it would be a good idea to use them. What are some examples that are either significantly more elegant/better with delegates or cant be solved using other methods?

我想我理解C#中委托的概念作为方法的指针,但是我找不到任何好的例子来说明使用它们的好主意。有哪些例子要么代表更优雅/更好,要么无法使用其他方法解决?

12 个解决方案

#1


What exactly do you mean by delegates? Here are two ways in which they can be used:

代表们究竟是什么意思?以下是两种可以使用它们的方法:

void Foo(Func<int, string> f) {
 //do stuff
 string s = f(42);
 // do more stuff
}

and

void Bar() {
 Func<int, string> f = delegate(i) { return i.ToString(); } 
//do stuff
 string s = f(42);
 // do more stuff
}

The point in the second one is that you can declare new functions on the fly, as delegates. This can be largely replaced by lambda expressions,and is useful any time you have a small piece of logic you want to 1) pass to another function, or 2) just execute repeatedly. LINQ is a good example. Every LINQ function takes a lambda expression as its argument, specifying the behavior. For example, if you have a List<int> l then l.Select(x=>(x.ToString()) will call ToString() on every element in the list. And the lambda expression I wrote is implemented as a delegate.

第二个问题的一点是,您可以像代表一样即时声明新功能。这可以在很大程度上被lambda表达式取代,并且只要你想要一小段逻辑1)传递给另一个函数,或者2)重复执行,它就很有用。 LINQ就是一个很好的例子。每个LINQ函数都使用lambda表达式作为参数,指定行为。例如,如果你有一个List l那么l.Select(x =>(x.ToString())将在列表中的每个元素上调用ToString()。我写的lambda表达式被实现为委托。

The first case shows how Select might be implemented. You take a delegate as your argument, and then you call it when needed. This allows the caller to customize the behavior of the function. Taking Select() as an example again, the function itself guarantees that the delegate you pass to it will be called on every element in the list, and the output of each will be returned. What that delegate actually does is up to you. That makes it an amazingly flexible and general function.

第一个案例显示了如何实现Select。你将一个代表作为你的论点,然后在需要时调用它。这允许调用者自定义函数的行为。再次以Select()为例,函数本身保证传递给它的委托将在列表中的每个元素上被调用,并且每个元素的输出都将被返回。该代表实际上做了什么取决于你。这使它成为一种非常灵活和通用的功能。

Of course, they're also used for subscribing to events. In a nutshell, delegates allow you to reference functions, using them as argument in function calls, assigning them to variables and whatever else you like to do.

当然,它们也用于订阅活动。简而言之,委托允许您引用函数,将它们用作函数调用中的参数,将它们分配给变量以及您想要执行的任何其他操作。

#2


The .NET 1.0 delegates:

.NET 1.0委托:

this.myButton.Click += new EventHandler(this.MyMethod);

The .NET 2.0 delegates:

.NET 2.0委托:

this.myOtherButton.Click += delegate {
    var res = PerformSomeAction();
    if(res > 5)
        PerformSomeOtherAction();
};

They seem pretty useful. How about:

它们似乎很有用。怎么样:

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

#3


I primarily use the for easy asynch programming. Kicking off a method using a delegates Begin... method is really easy if you want to fire and forget.

我主要使用for easy asynch编程。使用委托开始一个方法开始...方法如果你想要发射并忘记就很容易。

A delegate can also be used like an interface when interfaces are not available. E.g. calling methods from COM classes, external .Net classes etc.

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

#4


Events are the most obvious example. Compare how the observer pattern is implemented in Java (interfaces) and C# (delegates).

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

Also, a whole lot of the new C# 3 features (for example lambda expressions) are based on delegates and simplify their usage even further.

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

#5


For example in multithread apps. If you want several threads to use some control, You shoul use delegates. Sorry, the code is in VisualBasic.

例如,在多线程应用程序中。如果你想让几个线程使用一些控件,你应该使用委托。对不起,代码在VisualBasic中。

First you declare a delegate

首先,您声明一个委托

Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean)

Write a function to enable/disable button from several threads

编写一个函数来启用/禁用多个线程的按钮

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

#6


I use them all the time with LINQ, especially with lambda expressions, to provide a function to evaluate a condition or return a selection. Also use them to provide a function that will compare two items for sorting. This latter is important for generic collections where the default sorting may or may not be appropriate.

我一直使用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 ) );

#7


One of the benefits of Delegates is in asynchronous execution.

Delegates的一个好处是异步执行。

when you call a method asynchronously you do not know when it will finish executing, so you need to pass a delegate to that method that point to another method that will be called when the first method has completed execution. In the second method you can write some code that inform you the execution has completed.

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

#8


Technically delegate is a reference type used to encapsulate a method with a specific signature and return type

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

#9


Some other comments touched on the async world... but I'll comment anyway since my favorite 'flavor' of doing such has been mentioned:

其他一些评论触及了异步世界...但我还是会发表评论,因为我最喜欢这样做的“味道”:

ThreadPool.QueueUserWorkItem(delegate
{
    // This code will run on it's own thread!
});

Also, a huge reason for delegates is for "CallBacks". Let's say I make a bit of functionality (asynchronously), and you want me to call some method (let's say "AlertWhenDone")... you could pass in a "delegate" to your method as follows:

此外,代表们的一个重要原因是“CallBacks”。假设我做了一些功能(异步),你想让我调用一些方法(让我们说“AlertWhenDone”)......你可以将“委托”传递给你的方法,如下所示:

TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone);

#10


Outside of their role in events, which your probably familiar with if you've used winforms or asp.net, delegates are useful for making classes more flexible (e.g. the way they're used in LINQ).

除了你可能熟悉的事件之外,如果你使用了winforms或asp.net,那么代理对于使类更加灵活(例如它们在LINQ中的使用方式)非常有用。

Flexibility for "Finding" things is pretty common. You have a collection of things, and you want to provide a way to find things. Rather than guessing each way that someone might want to find things, you can now allow the caller to provide the algorithm so that they can search your collection however they see fit.

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

Here's a trivial code sample:

这是一个简单的代码示例:

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

}
}

Output

is

test

#11


there isn't really anything delgates will solve that can't be solved with other methods, but they provide a more elegant solution.

实际上并没有什么能够解决其他方法无法解决的问题,但它们提供了更优雅的解决方案。

With delegates, any function can be used as long as it has the required parameters.

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

The alternative is often to use a kind of custom built event system in the program, creating extra work and more areas for bugs to creep in

替代方案通常是在程序中使用一种自定义构建的事件系统,创建额外的工作和更多的区域来容纳蠕虫

#12


Is there an advantage to use a delegate when dealing with external calls to a database?

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

For example can code A :

例如可以代码A:

static void Main(string[] args) {

           DatabaseCode("test");

}

public void DatabaseCode(string arg) {

           .... code here ...

}

Be improved in code B :

在代码B中得到改进:

static void Main(string[] args) {

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

}

public void DatabaseCode(string arg) {

           .... code here ...

}
public delegate void DatabaseCodeDelegate(string arg);

It seems that this is subjective, but an area where there are strong conflicting view points?

这似乎是主观的,但这个观点有很强的冲突点?

#1


What exactly do you mean by delegates? Here are two ways in which they can be used:

代表们究竟是什么意思?以下是两种可以使用它们的方法:

void Foo(Func<int, string> f) {
 //do stuff
 string s = f(42);
 // do more stuff
}

and

void Bar() {
 Func<int, string> f = delegate(i) { return i.ToString(); } 
//do stuff
 string s = f(42);
 // do more stuff
}

The point in the second one is that you can declare new functions on the fly, as delegates. This can be largely replaced by lambda expressions,and is useful any time you have a small piece of logic you want to 1) pass to another function, or 2) just execute repeatedly. LINQ is a good example. Every LINQ function takes a lambda expression as its argument, specifying the behavior. For example, if you have a List<int> l then l.Select(x=>(x.ToString()) will call ToString() on every element in the list. And the lambda expression I wrote is implemented as a delegate.

第二个问题的一点是,您可以像代表一样即时声明新功能。这可以在很大程度上被lambda表达式取代,并且只要你想要一小段逻辑1)传递给另一个函数,或者2)重复执行,它就很有用。 LINQ就是一个很好的例子。每个LINQ函数都使用lambda表达式作为参数,指定行为。例如,如果你有一个List l那么l.Select(x =>(x.ToString())将在列表中的每个元素上调用ToString()。我写的lambda表达式被实现为委托。

The first case shows how Select might be implemented. You take a delegate as your argument, and then you call it when needed. This allows the caller to customize the behavior of the function. Taking Select() as an example again, the function itself guarantees that the delegate you pass to it will be called on every element in the list, and the output of each will be returned. What that delegate actually does is up to you. That makes it an amazingly flexible and general function.

第一个案例显示了如何实现Select。你将一个代表作为你的论点,然后在需要时调用它。这允许调用者自定义函数的行为。再次以Select()为例,函数本身保证传递给它的委托将在列表中的每个元素上被调用,并且每个元素的输出都将被返回。该代表实际上做了什么取决于你。这使它成为一种非常灵活和通用的功能。

Of course, they're also used for subscribing to events. In a nutshell, delegates allow you to reference functions, using them as argument in function calls, assigning them to variables and whatever else you like to do.

当然,它们也用于订阅活动。简而言之,委托允许您引用函数,将它们用作函数调用中的参数,将它们分配给变量以及您想要执行的任何其他操作。

#2


The .NET 1.0 delegates:

.NET 1.0委托:

this.myButton.Click += new EventHandler(this.MyMethod);

The .NET 2.0 delegates:

.NET 2.0委托:

this.myOtherButton.Click += delegate {
    var res = PerformSomeAction();
    if(res > 5)
        PerformSomeOtherAction();
};

They seem pretty useful. How about:

它们似乎很有用。怎么样:

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

#3


I primarily use the for easy asynch programming. Kicking off a method using a delegates Begin... method is really easy if you want to fire and forget.

我主要使用for easy asynch编程。使用委托开始一个方法开始...方法如果你想要发射并忘记就很容易。

A delegate can also be used like an interface when interfaces are not available. E.g. calling methods from COM classes, external .Net classes etc.

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

#4


Events are the most obvious example. Compare how the observer pattern is implemented in Java (interfaces) and C# (delegates).

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

Also, a whole lot of the new C# 3 features (for example lambda expressions) are based on delegates and simplify their usage even further.

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

#5


For example in multithread apps. If you want several threads to use some control, You shoul use delegates. Sorry, the code is in VisualBasic.

例如,在多线程应用程序中。如果你想让几个线程使用一些控件,你应该使用委托。对不起,代码在VisualBasic中。

First you declare a delegate

首先,您声明一个委托

Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean)

Write a function to enable/disable button from several threads

编写一个函数来启用/禁用多个线程的按钮

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

#6


I use them all the time with LINQ, especially with lambda expressions, to provide a function to evaluate a condition or return a selection. Also use them to provide a function that will compare two items for sorting. This latter is important for generic collections where the default sorting may or may not be appropriate.

我一直使用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 ) );

#7


One of the benefits of Delegates is in asynchronous execution.

Delegates的一个好处是异步执行。

when you call a method asynchronously you do not know when it will finish executing, so you need to pass a delegate to that method that point to another method that will be called when the first method has completed execution. In the second method you can write some code that inform you the execution has completed.

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

#8


Technically delegate is a reference type used to encapsulate a method with a specific signature and return type

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

#9


Some other comments touched on the async world... but I'll comment anyway since my favorite 'flavor' of doing such has been mentioned:

其他一些评论触及了异步世界...但我还是会发表评论,因为我最喜欢这样做的“味道”:

ThreadPool.QueueUserWorkItem(delegate
{
    // This code will run on it's own thread!
});

Also, a huge reason for delegates is for "CallBacks". Let's say I make a bit of functionality (asynchronously), and you want me to call some method (let's say "AlertWhenDone")... you could pass in a "delegate" to your method as follows:

此外,代表们的一个重要原因是“CallBacks”。假设我做了一些功能(异步),你想让我调用一些方法(让我们说“AlertWhenDone”)......你可以将“委托”传递给你的方法,如下所示:

TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone);

#10


Outside of their role in events, which your probably familiar with if you've used winforms or asp.net, delegates are useful for making classes more flexible (e.g. the way they're used in LINQ).

除了你可能熟悉的事件之外,如果你使用了winforms或asp.net,那么代理对于使类更加灵活(例如它们在LINQ中的使用方式)非常有用。

Flexibility for "Finding" things is pretty common. You have a collection of things, and you want to provide a way to find things. Rather than guessing each way that someone might want to find things, you can now allow the caller to provide the algorithm so that they can search your collection however they see fit.

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

Here's a trivial code sample:

这是一个简单的代码示例:

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

}
}

Output

is

test

#11


there isn't really anything delgates will solve that can't be solved with other methods, but they provide a more elegant solution.

实际上并没有什么能够解决其他方法无法解决的问题,但它们提供了更优雅的解决方案。

With delegates, any function can be used as long as it has the required parameters.

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

The alternative is often to use a kind of custom built event system in the program, creating extra work and more areas for bugs to creep in

替代方案通常是在程序中使用一种自定义构建的事件系统,创建额外的工作和更多的区域来容纳蠕虫

#12


Is there an advantage to use a delegate when dealing with external calls to a database?

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

For example can code A :

例如可以代码A:

static void Main(string[] args) {

           DatabaseCode("test");

}

public void DatabaseCode(string arg) {

           .... code here ...

}

Be improved in code B :

在代码B中得到改进:

static void Main(string[] args) {

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

}

public void DatabaseCode(string arg) {

           .... code here ...

}
public delegate void DatabaseCodeDelegate(string arg);

It seems that this is subjective, but an area where there are strong conflicting view points?

这似乎是主观的,但这个观点有很强的冲突点?