C# 无法理解代理在真实场景中的使用

C# 无法理解代理在真实场景中的使用,c#,delegates,C#,Delegates,我无法理解在.NET世界中如何正确使用委托。哪些问题不能通过代表解决?我想知道什么样的场景/情况是理想的或适合代表使用的 我知道LINQ和Lambda表达式都在幕后使用代理。我知道如何创建和使用它,但我没有理解的是为什么我应该创建和使用它们 任何真实世界的例子或经验分享将不胜感激 更新: 我创建了以下类 using System; using System.Collections.Generic; using System.Linq; namespace Basics { public cla

我无法理解在.NET世界中如何正确使用委托。哪些问题不能通过代表解决?我想知道什么样的场景/情况是理想的或适合代表使用的

我知道LINQ和Lambda表达式都在幕后使用代理。我知道如何创建和使用它,但我没有理解的是为什么我应该创建和使用它们

任何真实世界的例子或经验分享将不胜感激

更新:

我创建了以下类

using System;
using System.Collections.Generic;
using System.Linq;

namespace Basics
{
public class Program
{
    static void Main()
    {
        Flight.FlightTakeOffDelegate flightDelegate;

        var flights = new List<Flight>
            {
                new Flight {Number = "FL001", DepartureTime = DateTime.Now, TotalCrew = 15},
                new Flight {Number = "FL002", DepartureTime = DateTime.Now.AddHours(1), TotalCrew = 15},
                new Flight {Number = "FL003", DepartureTime = DateTime.Now.AddHours(2), TotalCrew = 15},                    
            };

        var tower = new FlightTower(flights);

        // Flight 002 asking to Take off
        var flightAskingToTakeOff = flights.FirstOrDefault(x => x.Number == "FL002");
        if (flightAskingToTakeOff != null)
        {
            Console.WriteLine(string.Format("Flight {0} \t: Okay to take off?", flightAskingToTakeOff.Number));
            flightDelegate = tower.CanTakeOff;
            flightAskingToTakeOff.CanTakeOff = flightDelegate.Invoke(flightAskingToTakeOff);
            Console.WriteLine(string.Format("Flight Tower \t: {0}", flightAskingToTakeOff.CanTakeOff));
        }

        // Flight 001 asking to Take off
        flightAskingToTakeOff = flights.FirstOrDefault(x => x.Number == "FL001");
        if (flightAskingToTakeOff != null)
        {
            Console.WriteLine(string.Format("Flight {0} \t: Okay to take off?", flightAskingToTakeOff.Number));
            flightDelegate = tower.CanTakeOff;
            flightAskingToTakeOff.CanTakeOff = flightDelegate.Invoke(flightAskingToTakeOff);
            Console.WriteLine(string.Format("Flight Tower \t: {0}", flightAskingToTakeOff.CanTakeOff));
        }

        Console.ReadKey();
    }
}

public class FlightTower
{
    private readonly List<Flight> _schedule;

    public FlightTower(List<Flight> schedule)
    {
        _schedule = schedule;
    }


    public bool CanTakeOff(Flight flight)
    {            
        var arrivingFlights = _schedule.Where(x => x.ArrivalTime == DateTime.Now);

        if (!arrivingFlights.Any())
        {

            var flightInQueue = _schedule.FirstOrDefault(x => x.DepartureTime == _schedule.Min(c=> c.DepartureTime));
            if (flightInQueue != null && flightInQueue.Number == flight.Number)
            {                    
                return true;
            }
        }

        return false;
    }
}


public class Flight
{
    public delegate bool FlightTakeOffDelegate(Flight flight);

    public string Number { get; set; }
    public DateTime DepartureTime { get; set; }
    public DateTime ArrivalTime { get; set; }
    public int TotalCrew { get; set; }
    public bool CanTakeOff { get; set; }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间基础
{
公共课程
{
静态void Main()
{
Flight.FlightTakeOffDelegate flightDelegate;
var flights=新列表
{
新航班{Number=“FL001”,起飞时间=日期时间。现在,全员=15},
新航班{Number=“FL002”,起飞时间=DateTime.Now.AddHours(1),总机组人数=15},
新航班{Number=“FL003”,起飞时间=DateTime.Now.AddHours(2),总机组人数=15},
};
var塔=新飞行塔(飞行);
//002航班要求起飞
var flightaskingtoakeoff=flights.FirstOrDefault(x=>x.Number==“FL002”);
if(flightAskingToTakeOff!=null)
{
WriteLine(string.Format(“航班{0}\t:可以起飞吗?”,航班askingtoakeoff.Number));
flightDelegate=tower.CanTakeOff;
flightaskingtoakeoff.CanTakeOff=flightDelegate.Invoke(flightaskingtoakeoff);
WriteLine(string.Format(“flighttower\t:{0}”,flightAskingToTakeOff.CanTakeOff));
}
//001航班要求起飞
flightAskingToTakeOff=flights.FirstOrDefault(x=>x.Number==“FL001”);
if(flightAskingToTakeOff!=null)
{
WriteLine(string.Format(“航班{0}\t:可以起飞吗?”,航班askingtoakeoff.Number));
flightDelegate=tower.CanTakeOff;
flightaskingtoakeoff.CanTakeOff=flightDelegate.Invoke(flightaskingtoakeoff);
WriteLine(string.Format(“flighttower\t:{0}”,flightAskingToTakeOff.CanTakeOff));
}
Console.ReadKey();
}
}
公共级飞行塔
{
私有只读列表\u时间表;
公共飞行塔(列表附表)
{
_时间表=时间表;
}
公共厕所(航班)
{            
var arrivingFlights=_schedule.Where(x=>x.ArrivalTime==DateTime.Now);
如果(!arrivingFlights.Any())
{
var flightInQueue=_schedule.FirstOrDefault(x=>x.DepartureTime==_schedule.Min(c=>c.DepartureTime));
if(flightInQueue!=null&&flightInQueue.Number==flightInQueue.Number)
{                    
返回true;
}
}
返回false;
}
}
公务舱航班
{
公共代表bool FlightTakeOffDelegate(航班飞行);
公共字符串编号{get;set;}
public DateTime DepartureTime{get;set;}
公共日期时间到达时间{get;set;}
公共整数TotalCrew{get;set;}
公共bool CanTakeOff{get;set;}
}
}


任何人都可以看看在这种情况下如何使用委托吗?

事件处理程序是委托使用的完美示例

GUI代码使用委托来处理事件,例如按钮单击、窗口移动。使用委托允许您在事件发生时调用函数。例如,将保存数据的函数链接到界面上的“保存”按钮。单击按钮时,将设置为执行保存数据的功能。它在GUI编程中很有用,因为您的整个程序可能都在等待用户做一些事情,而您无法知道他们将首先做什么。通过使用委托,可以将程序的功能连接到用户界面,用户可以按照自己想要的方式进行操作

例如:

我有一个人为但清晰的例子给你

假设您有一组消息

public class Message  
{
    public string Tag {get;set;}
    public byte[] RawData{ get;set;}
}
你从队列中得到它们

您想要解析它们

public class Parser 
{
    private Dictionary<string, Func<Message, string>> _handlers = 
                               new Dictionary<string, Func<Message, string>>
    {
        {"Tag1", (message) => {here are parse rules}},
        {"Tag2", (message) => {here are parse rules2}},
    }

    public string Handle(Message message)
    {
        var handler = _handlers[message.Tag];
        return handler(message);
    }
}
公共类解析器
{
专用字典_处理程序=
新词典
{
{“Tag1”,(message)=>{这里是解析规则}},
{“Tag2”,(message)=>{这里是解析规则2}},
}
公共字符串句柄(消息)
{
var handler=_handlers[message.Tag];
返回处理程序(消息);
}
}

如您所见,您可以将任何委托视为普通对象。您可以存储集合,也可以将它们传递给其他方法等等。

委托非常类似于函数指针。它是与方法签名匹配的类型。委托的实例可以绑定到具有该签名的方法。这允许您传递对周围方法的引用,甚至传递到对实际方法不可见的对象中

在现实世界中,当启动一个新线程时,会用到这个方法。ThreadPool类有一个静态方法来为新线程排队。但是您需要向它传递一个从新线程调用的方法。为此,需要一个委托参数:

public static bool QueueUserWorkItem(WaitCallback callBack)
WaitCallback是一个委托,它匹配具有void(object)签名的任何方法:

public delegate void WaitCallback(object state)
因此,如果你有一个方法:

void MyMethod(object state)
{

}
您可以将指向此方法的“指针”传递给QueueUserWorkItem,以便它以后可以调用它(ThreadPool不需要任何类的知识)


委托不允许您执行无法执行的任务,但它们允许您使用更干净、更模块化的代码实现相同的结果。这个概念与泛型/接口或抽象类的实现非常相似,但它适用于操作和函数,而不是对象和属性

那么让我们说哟
void Func()
{
    WaitCallback wc = new WaitCallback(MyMethod)
    ThreadPool.QueueUserWorkItem(wc);
}