/* 委托类型
* 委托类型定义了委托实例可以调用的那类方法,定义了方法的返回类型和参数
* 一个委托实例可以调用一组目标方法,(多播能力)
* 委托时不可变的,当使用+=,-=时,实际上时创建了新的委托实例,并把它赋值给当前的委托变量
* 如果多播委托的返回类型不是void,那么调用者会从最后一个被调用的方法来接受返回值,当前方法仍被调用,但是返回值被弃用
*
* 泛型委托可以写出一组委托类型,他们可以调用的方法可以拥有任意返回类型和任意(合理)数量的参数 Func,Action
*
* 委托可以解决的问题,接口都可以解决,接口只能实现一个方法,需要多播功能,订阅者需要多次实现接口时可以使用委托
*
* 委托类型之间互不相容,如果委托实例拥有相同的目标方法时,那么委托实例就认为是相等的
*
* 当调用一个方法时,提供的参数比调用方法需要的参数类型更具体,委托就可以接受比它方法更具体的类型,ContraVariance
* 同理 返回类型也一样,Covariance
*
* 使用委托的时候通常会有一个广播者和一个订阅者,广播者这类类型包含一个委托字段,
* 广播者可以通过调用委托来决定什么时候进行广播
* 订阅者是方法目标的接收者,订阅者可以决定何时开始或结束监听,方式是通过在委托中调用 += -=
* 一个订阅者不知道和不干扰其他订阅者
*
* 事件event是一种结构,为了实现上述模式,它只暴露了所需委托特性的子集
* 事件的目的是为了防止订阅者之间相互干扰
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LambDa.Properties;
namespace LambDa
{
public delegate int TransForm(int x);
public delegate void Instance(int x);
public delegate T TransFormer<T>(T arg);
public delegate void stringAction(string str);
public delegate object ObjectRet();
class Program
{
static int Add(int x)
{
return x * x;
}
static int Cube(int x)
{
return x * x * x;
}
static void Main(string[] args)
{
Stock stock = new Stock("商品");
stock.Price = 120;
stock.PriceChanged += stock.stock_pricechanged;
stock.Price = 130;
string msg = "委托接受更具体的参数描述";
stringAction s = null;
s += Unit.ActionObject;
s(msg);
ObjectRet o = null;
o += X.Retstring;
Object resl = o();
Console.WriteLine(resl);
int[] values = { 1, 2, 3 };
Unit.TransFormer(values, Add);
foreach(var i in values)
{
Console.WriteLine(i);
}
TransForm t = null;
t += Add;
t += Cube;
int result = t(3);
Console.WriteLine(result);
Unit.TransForm(values, Add);
foreach(var i in values)
{
Console.WriteLine(i);
}
X x = new X();
Instance p = x.PingFang;
p(5);
Console.WriteLine(p.Target);
Console.WriteLine(p.Method);
Console.ReadKey();
}
}
class Unit
{
public static void TransForm (int[] values,TransForm t)
{
for(int i = 0; i < values.Length; i++)
{
values[i] = t(values[i]);
}
}
public static void TransFormer<T>(T[] values,Func<T,T> t)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = t(values[i]);
}
}
public static void ActionObject(object o)
{
Console.WriteLine(o);
}
}
class X
{
public void PingFang(int can)
=> Console.WriteLine(can * can);
public static string Retstring() => "hello!";
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LambDa.Properties
{
public class PriceChangeMsg : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangeMsg(decimal lastprice, decimal newprice)
{
LastPrice = lastprice;
NewPrice = newprice;
}
}
public class Stock
{
string name;
decimal price;
public Stock(string Name)
{
this.name = Name;
}
public event EventHandler<PriceChangeMsg> PriceChanged;
protected virtual void OnPriceChanged(PriceChangeMsg e)
{
PriceChanged?.Invoke(this, e);
}
public decimal Price
{
get { return price; }
set
{
if (Price == value)
{
return;
}
else
{
decimal OldPrice = price;
price = value;
OnPriceChanged(new PriceChangeMsg(OldPrice, price));
}
}
}
public void stock_pricechanged(object sender, PriceChangeMsg e)
{
if ((e.NewPrice - e.LastPrice) > 0)
{
Console.WriteLine("商品涨价");
}
}
}
}