首页 新闻 搜索 专区 学院

关于委托的一个问题

0
悬赏园豆:20 [待解决问题]
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直接作为参数。

C#
birchlee的主页 birchlee | 初学一级 | 园豆:105
提问于:2012-06-08 09:26
< >
分享
所有回答(3)
0
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();
        }
    }

 

无之无 | 园豆:5085 (大侠五级) | 2012-06-08 10:11

我在模拟delegate的实现原理,你这里用了delegate

支持(0) 反对(0) birchlee | 园豆:105 (初学一级) | 2012-06-08 10:12

@BirchLee: 你为什么会有这个想法?要做到这个不是不可以,而是很麻烦,难度很大。

delegate定义的就是一个函数调用规范,当把一个函数名赋值给一个delegate类型的对象时,其实赋值的是函数的地址,这里面牵涉到太多的封装与解封了。

如果你想要这样,建议你反编译.NET类库查看一下。

支持(0) 反对(0) 无之无 | 园豆:5085 (大侠五级) | 2012-06-08 10:16

@笨笨蜗牛: 反编译查看了,原理我也参照Artech的文章做出了模拟,但是唯一困惑的就是 类名.方法名这种传递参数的机制是如何实现的。

支持(0) 反对(0) birchlee | 园豆:105 (初学一级) | 2012-06-08 10:21

@BirchLee: 反射

支持(0) 反对(0) Ethan轻叹 | 园豆:996 (小虾三级) | 2012-06-08 13:45
0

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();
}

船长&CAP | 园豆:318 (菜鸟二级) | 2012-06-08 10:41

我在模拟delegate的实现原理,你这里用了delegate

支持(0) 反对(0) birchlee | 园豆:105 (初学一级) | 2012-06-08 10:47

@BirchLee: 如果你的意思是委托的机制的话。函数指针。这在框架下不容易体现。查查 MSDN 关于不安全代码,使用指针。

支持(0) 反对(0) 船长&CAP | 园豆:318 (菜鸟二级) | 2012-06-08 11:03
0

委托,会编译成一个类,里面四个方法,构造方法,invoke, begininvoke和endinvoke(用于异步)。

构造方法传,对象和方法,如果静态犯法,对象参数为null,invoke负责调用。

delegate里面还有其他方法和属性,比如用于管理多播委托muticasedelegate,里面有combine,remove方法管理委托,底层有delegate[] 数组作为基层容器。

你知道了这些就可以明白该怎么做了。

Ethan轻叹 | 园豆:996 (小虾三级) | 2012-06-08 13:52

类似EventHandler这样的一个类,也继承自muticasedelegate,我问的是  类名.方法名  这种传参机制是如何实现的,跟 Delegate的 Combine没关系吧。

支持(0) 反对(0) birchlee | 园豆:105 (初学一级) | 2012-06-08 13:55

@BirchLee: 你需要的东西是在前半段。

支持(0) 反对(0) Ethan轻叹 | 园豆:996 (小虾三级) | 2012-06-08 14:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册