c#中代表的主要目的是什么? [英] what is the main purpose of delegates in c#?
问题描述
c#中代理的主要目的是什么?
what is the main purpose of delegates in c#?
推荐答案
基本上,它们将方法指定为类型,包括签名规范。
我一直都在使用它们。以下是一些真实世界的例子:
我有自定义网页控件。如果控件被赋予Label,则两个控件都被包装在一起。我可以将Render方法作为代理传递:
Basically they specify a method as a type, including signature specification.
I use them all the time. Here are some real world examples:
I have custom web controls. If the control is given a Label then both controls are wrapped together. I can pass Render methods as delegates:
//This is my render method delegate
public delegate void HtmlRenderMethod(HtmlTextWriter writer);
public override void Render(HtmlTextWriter writer){
if(!string.IsnullOrEmpty(Label)){
RenderWrapper(base.Render,writer); //method must match signature
}
else{
base.Render(writer);
}
}
private void RenderWrapper(HtmlRenderMethod method, HtmlTextWriter writer){
writer.RenderOpenTag("div");
RenderLabel(writer);
method(writer); //I can use it just like a method
writer.RenderCloseTag();
}
我的渲染方法要复杂得多。例如,我有继承TextBox的基础ValidatedTextbox,但我有其他从ValidatedTextbox继承的控件。如果我想要访问TextBox Render方法而不必通过ValidatedTextbox渲染方法,那么我可以将原始方法保存在受保护的变量中并从任何祖先调用它。
我还启动了自定义工作流引擎。这将在消息到方法的基础上运行。我需要知道什么方法处理什么样的消息。为此,我创建了一个委托并创建了一个字典< message,method>:
My render methods are far more complex that this. For example I have the base ValidatedTextbox that inherits TextBox but I have other controls that inherit from ValidatedTextbox. If I want access to the TextBox Render method without having to go through the ValidatedTextbox render method then I can just save the original method in a protected variable and call it from any ancestor.
I have also started my custom workflow engine. This will operate on a message-to-method basis. I need to know what method handles what kind of message. To do this I create a delegate and create a dictionary<message,method>:
public delegate Engine.WorkflowResult MessageHandler(IMessage message);
public class MessageHandlerList : Dictionary<type,>
{
public Engine.WorkflowResult TryParse(IMessage message)
{
if (!ContainsKey(message.GetType()))
return WorkflowResult.Wait;
return this[message.GetType()](message);
}
public new bool ContainsKey(Type key)
{
return Keys.Any(k => k.GUID == key.GUID);
}
public new MessageHandler this[Type key]
{
get { return base[Keys.Single(k => k.GUID == key.GUID)]; }
set { base[Keys.Single(k => k.GUID == key.GUID)] = value; }
}
}
...
private MessageHandlerList _messageHandlers {get;set;}
public void Initialize(){
_messageHandlers = new MessageHandlerList();
_messageHandlers.Add(ProcessStartMessage,ProcessStartHandle);
_messageHandlers.Add(ProcessEndMessage,ProcessEndHandle);
}
public Engine.WorkflowResult ParseMessage(IMessage message){
return _messageHandlers.TryParse(message)
}
private Engine.WorkflowResult ProcessStartHandle(IMessage message){
if(!message.Deserialized)
message.Deserialize();
ProcessStartMessage startMessage = (ProcessStartMessage)message;
//do stuff
}
private Engine.WorkflowResult ProcessEndHandle(IMessage message){
if(!message.Deserialized)
message.Deserialize();
ProcessEndMessage startMessage = (ProcessEndMessage)message;
//do stuff
}
...
我在数据库上包装事务时也使用委托。我使用更开放的委托,所以我可以得到任何我喜欢的返回类型,只要核心委托返回void:
I also use delegates when I wrap transactions on the database. I use a more open delegate so I can get any return type I like, so long as the core delegate returns void:
public delegate void Transaction();
public static void TransactionWrapper(Transaction transaction)
{
var options = new TransactionOptions
{
IsolationLevel = IsolationLevel.Snapshot,
Timeout = TimeSpan.FromSeconds(120)
};
using (var scope = new TransactionScope(TransactionScopeOption.Required, options))
{
transaction();
scope.Complete();
}
}
...
public List<message> SelectAllDue(DatabaseContext db = null){
if(db==null)
db = new DatabaseContext();
List<messages> result = null;
//inline use of delegate
TrasactionWrapper(()=>{
var query = db.Messages;
query = query.Where(m=>m.Due < DateTime.Now);
result = query.ToList();
}
return result
}
...</messages></message>
你还可以做很多其他聪明的事情。你甚至可以拥有复合代表团。
每个Lamda表达在技术上都是一个代表
这些是一些'真实世界'的例子s,我为了简单起见而修剪过。
There are many other clever things you can do as well. You can have composite delegate groups even.
Every Lamda expression is technically a delegate
These are a few 'real world' examples, that I have trimmed for simplicity.
参见 http://msdn.microsoft.com/en-us/library/aa288436(VS.71).aspx [ ^ ]。
这篇关于c#中代表的主要目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!