你什么时候会在 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
When would you use delegates in C#?
提问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
For event handler
To pass method in a method parameters
对于事件处理程序
在方法参数中传递方法
回答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.CreateDelegate
to 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 Expression
that 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 Expression
to 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
代表的使用
- Event Handling
- Multi Casting
- 事件处理
- 多播