namespace ex01 { class Program { static void Main(string[] args) { MySayHiDelegate dlSayHi1 = new MySayHiDelegate(typeof(Chinese), "SayHi"); dlSayHi1.Invoke("李峻桦"); MySayHiDelegate dlSayHi2 = new MySayHiDelegate(new American(), "SayHi"); dlSayHi2.Invoke("李峻桦"); Console.ReadLine(); } } public class MySayHiDelegate { public MethodInfo Method { get; set; } public Object Target { get; set; } //实例方法 public MySayHiDelegate(Object target, string method) { Type type = target.GetType(); this.Target = target; MemberInfo[] methodInfos = type.GetMethods(); foreach (MethodInfo methodInfo in methodInfos) { if (String.Compare(methodInfo.Name, method, true) == 0) { this.Method = methodInfo; break; } } } //静态方法 public MySayHiDelegate(Type target, string method) { this.Target = null; MemberInfo[] methodInfos = target.GetMethods(); foreach (MethodInfo methodInfo in methodInfos) { if (String.Compare(methodInfo.Name, method, true) == 0) { this.Method = methodInfo; break; } } } public virtual void Invoke(string userName) { this.Method.Invoke(this.Target, new object[] { userName }); } } public class Chinese { public static void SayHi(string userName) { Console.WriteLine(userName + "你好!"); } } public class American { public void SayHi(string userName) { Console.WriteLine(userName + " Nice to meet you!"); } } }
请问如何模拟 delegate那种传值方式, Chinese.SayHi直接作为参数。
public delegate void SayHiHandler(string userName); public class MySayHiDelegate { public SayHiHandler SayHi { get; private set; } //实例方法 public MySayHiDelegate(SayHiHandler handler) { SayHi = handler; } }
class Program { static void Main(string[] args) { MySayHiDelegate dlSayHi1 = new MySayHiDelegate(Chinese.SayHi); dlSayHi1.SayHi("李峻桦"); MySayHiDelegate dlSayHi2 = new MySayHiDelegate(new American().SayHi); dlSayHi2.SayHi("李峻桦"); Console.ReadLine(); } }
我在模拟delegate的实现原理,你这里用了delegate
@BirchLee: 你为什么会有这个想法?要做到这个不是不可以,而是很麻烦,难度很大。
delegate定义的就是一个函数调用规范,当把一个函数名赋值给一个delegate类型的对象时,其实赋值的是函数的地址,这里面牵涉到太多的封装与解封了。
如果你想要这样,建议你反编译.NET类库查看一下。
@笨笨蜗牛: 反编译查看了,原理我也参照Artech的文章做出了模拟,但是唯一困惑的就是 类名.方法名这种传递参数的机制是如何实现的。
@BirchLee: 反射
public delegate void MyEventHandler(string str);
static void Main(string[] args)
{
MyEventHandler m = new MyEventHandler(Chinese.SayHi);
m("Chinese");
Console.ReadLine();
}
或
public delegate void MyEventHandler(string str);
static void Main(string[] args)
{
MyEventHandler m = (x) => { Chinese.SayHi(x); };
m("Chinese");
Console.ReadLine();
}
委托,会编译成一个类,里面四个方法,构造方法,invoke, begininvoke和endinvoke(用于异步)。
构造方法传,对象和方法,如果静态犯法,对象参数为null,invoke负责调用。
delegate里面还有其他方法和属性,比如用于管理多播委托muticasedelegate,里面有combine,remove方法管理委托,底层有delegate[] 数组作为基层容器。
你知道了这些就可以明白该怎么做了。
类似EventHandler这样的一个类,也继承自muticasedelegate,我问的是 类名.方法名 这种传参机制是如何实现的,跟 Delegate的 Combine没关系吧。
@BirchLee: 你需要的东西是在前半段。