你什么时候会在 C# 中使用委托?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/191153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:24:55  来源:igfitidea点击:

When would you use delegates in C#?

c#.netdelegates

提问by Maxime Rouiller

What are your usage of delegates in C#?

你在 C# 中使用委托的方式是什么?

采纳答案by Jon Skeet

Now that we have lambda expressions and anonymous methods in C#, I use delegates much more. In C# 1, where you always had to have a separate method to implement the logic, using a delegate often didn't make sense. These days I use delegates for:

现在我们在 C# 中有 lambda 表达式和匿名方法,我更多地使用委托。在 C# 1 中,您总是必须有一个单独的方法来实现逻辑,使用委托通常没有意义。这些天我使用委托:

  • Event handlers (for GUI and more)
  • Starting threads
  • Callbacks (e.g. for async APIs)
  • LINQ and similar (List.Find etc)
  • Anywhere else where I want to effectively apply "template" code with some specialized logic inside (where the delegate provides the specialization)
  • 事件处理程序(用于 GUI 等)
  • 启动线程
  • 回调(例如异步 API)
  • LINQ 和类似的(List.Find 等)
  • 我想有效地应用带有一些专门逻辑的“模板”代码的其他任何地方(委托提供专业化的地方)

回答by Manu

subscribing eventhandlers to events

为事件订阅事件处理程序

回答by Patrick Desjardins

  1. For event handler

  2. To pass method in a method parameters

  1. 对于事件处理程序

  2. 在方法参数中传递方法

回答by x0n

The first line of usage is to replace the Observer/Observable (events) pattern. The second, a nice elegant version of the Strategy pattern. Various other usages can be gathered, though more esoteric than these first two I think.

第一行用法是替换 Observer/Observable(事件)模式。第二,策略模式的优雅版本。可以收集各种其他用法,尽管我认为比前两个更深奥。

回答by x0n

Events, other anynch operations

事件,其他 anynch 操作

回答by Bob King

Any time you want to encapsulate behavior, but invoke it in a uniform way. Event Handlers, call-back functions, etc. You can accomplish similar things using Interfaces and casts, but sometimes, behavior isn't necessarily tied to a typeor object. Sometimes you just have behavior you need to encapsulate.

任何时候你想封装行为,但以统一的方式调用它。事件处理程序、回调函数等。您可以使用接口和强制转换来完成类似的事情,但有时,行为不一定与类型对象相关联。有时,您只需要封装一些行为。

回答by Santiago Palladino

Lazy parameter initialization! Besides all previous answers (strategy pattern, observer pattern, etc), delegates allow you to handle lazy initialization of parameters. For example, suppose you have a function Download() which takes quite a lot of time and returns a certain DownloadedObject. This object is consumed by a Storage depending on a certain Conditions. Typically, you would:

懒惰的参数初始化!除了之前的所有答案(策略模式、观察者模式等)之外,委托还允许您处理参数的延迟初始化。例如,假设您有一个函数 Download(),它需要花费大量时间并返回某个 DownloadedObject。该对象由存储根据特定条件使用。通常,您会:

storage.Store(conditions, Download(item))

However, with delegates (more precisely, lambdas) you can do the following, by changing the signature of store so that it receives a Condition and a Func<Item,DownloadedObject> and use it like this:

但是,对于委托(更准确地说,是 lambdas),您可以通过更改 store 的签名来执行以下操作,以便它接收一个 Condition 和一个 Func<Item,DownloadedObject> 并像这样使用它:

storage.Store(conditions, (item) => Download(item))

Therefore, storage will only evaluate the delegate if necessary, executing download depending on Conditions.

因此,存储只会在必要时评估委托,根据条件执行下载。

回答by Marc Gravell

A slightly different use is to speed up reflection; i.e. instead of using reflection each time, you can use Delegate.CreateDelegateto create a (typed) delegate to a method (a MethodInfo), and call that delegate instead. This is then muchquicker per call, as the checks have already been done.

一个稍微不同的用途是加速反射;即不是每次都使用反射,您可以使用Delegate.CreateDelegate为方法 (a MethodInfo)创建(类型化)委托,然后调用该委托。这是那么多的每次呼叫更快,因为检查已经完成。

With Expression, you can also do the same to create code on the fly - for example, you can easily create an Expressionthat represents the + operator for a type chosen at runtime (to provide operator support for generics, which the language doesn't provide); and you can compile an Expressionto a typed delegate - job done.

使用Expression,您还可以执行相同的操作来动态创建代码 - 例如,您可以轻松地创建一个Expression表示运行时选择的类型的 + 运算符(以提供对泛型的运算符支持,该语言不提供) ; 并且您可以将 an 编译Expression为类型化的委托 - 工作完成。

回答by harpo

You can use delegates to declare function-typed variables and parameters.

您可以使用委托来声明函数类型的变量和参数。

Example

例子

Consider the "resource borrowing" pattern. You want to control the creation and cleanup of a resource, while allowing client code to "borrow" the resource in between.

考虑“资源借用”模式。您希望控制资源的创建和清理,同时允许客户端代码在两者之间“借用”资源。

This declares a delegate type.

这声明了一个委托类型。

public delegate void DataReaderUser( System.Data.IDataReader dataReader );

Any method matching this signature can be used to instantiate a delegate of this type. In C# 2.0, this can be done implicitly, simply by using method's name, as well as by using anonymous methods.

任何匹配此签名的方法均可用于实例化此类型的委托。在 C# 2.0 中,这可以隐式完成,只需使用方法的名称,也可以使用匿名方法。

This method uses the type as a parameter. Note the delegate's invocation.

此方法使用类型作为参数。注意委托的调用。

public class DataProvider
{
    protected string _connectionString;

    public DataProvider( string psConnectionString )
    {
        _connectionString = psConnectionString;
    }

    public void UseReader( string psSELECT, DataReaderUser readerUser )
    {
        using ( SqlConnection connection = new SqlConnection( _connectionString ) )
        try
        {
            SqlCommand command = new SqlCommand( psSELECT, connection );
            connection.Open();
            SqlDataReader reader = command.ExecuteReader();

            while ( reader.Read() )
                readerUser( reader );  // the delegate is invoked
        }
        catch ( System.Exception ex )
        {
            // handle exception
            throw ex;
        }
    }
}

The function can be called with an anonymous method as follows. Note that the anonymous method can use variables declared outsideof itself. This is extremely handy (although the example is a little contrived).

可以使用匿名方法调用该函数,如下所示。请注意,匿名方法可以使用自身之外声明的变量。这非常方便(虽然这个例子有点做作)。

string sTableName = "test";
string sQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + sTableName + "'";

DataProvider.UseReader( sQuery,
    delegate( System.Data.IDataReader reader )
    {
        Console.WriteLine( sTableName + "." + reader[0] );
    } );

回答by Rajeshwaran S P

Usage of delegates

代表的使用

  1. Event Handling
  2. Multi Casting
  1. 事件处理
  2. 多播