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