c#中代表的主要目的是什么? [英] what is the main purpose of delegates in c#?

查看:73
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆