今天看了看EventHandler<(Of <(TEventArgs>)>) 泛型委托
发现msdn示例// This example demonstrates the EventHandler<T> delegate.using System;
using System.Collections.Generic;//---------------------------------------------------------
public class MyEventArgs : EventArgs
{
    private string msg;    public MyEventArgs( string messageData ) {
        msg = messageData;
    }
    public string Message { 
        get { return msg; } 
        set { msg = value; }
    }
}
//---------------------------------------------------------
public class HasEvent
{
// Declare an event of delegate type EventHandler of 
// MyEventArgs.    public event EventHandler<MyEventArgs> SampleEvent;    public void DemoEvent(string val)
    {
/**********************************************************
    // Copy to a temporary variable to be thread-safe.复制到临时变量,以确保线程安全
***************************************************************/
        EventHandler<MyEventArgs> temp = SampleEvent;
        if (temp != null)
            temp(this, new MyEventArgs(val));
    }
}
//---------------------------------------------------------
public class Sample
{
    public static void Main()
    {
        HasEvent he = new HasEvent();
        he.SampleEvent += 
                   new EventHandler<MyEventArgs>(SampleEventHandler);
        he.DemoEvent("Hey there, Bruce!");
        he.DemoEvent("How are you today?");
        he.DemoEvent("I'm pretty good.");
        he.DemoEvent("Thanks for asking!");
    }
    private static void SampleEventHandler(object src, MyEventArgs mea)
    {
        Console.WriteLine(mea.Message);
    }
}
//---------------------------------------------------------
/*
This example produces the following results:Hey there, Bruce!
How are you today?
I'm pretty good.
Thanks for asking!*/
突然看到了这句
/**********************************************************
    // Copy to a temporary variable to be thread-safe.复制到临时变量,以确保线程安全
***************************************************************/值类型:整型、布尔型、字符型、实数型、结构型、枚举型。
引用类型:类、对象、字符串、数组、接口、委托。我的理解
引用类型能这样实现线程安全吗?
而且委托本身不就是函数指针吗???
望高手指点

解决方案 »

  1.   

    要自己动手做做测试。he.SampleEvent += new EventHandler<MyEventArgs>(SampleEventHandler);
    执行它后。he.SampleEvent所指向的实体变了。复制它,是为了防止这样的变化。
    你运行下面的看看。EventHandler<EventArgs> list = new EventHandler<EventArgs>(test);
    EventHandler<EventArgs> list1 = list;
    list += new EventHandler<EventArgs>(test);MessageBox.Show((list1 == list).ToString());
    List<string> sl = new List<string>();
    List<string> sl1 = sl;
    sl.Add(string.Empty);MessageBox.Show((sl1 == sl).ToString());
      

  2.   

    EventHandler<EventArgs> list = new EventHandler<EventArgs>(test);
    EventHandler<EventArgs> list1 = list;
    list += new EventHandler<EventArgs>(test);可以帮我解释解释吗?具体的引用关系。为什么会不相等啊!
      

  3.   


    cout << "还是喜欢C++" << endl;
      

  4.   

    你自己debug去跟踪一下,或找找msdnEventHandler 的+= 操作,他把所有的委托都是放在 Array里面的,用[Index]访问。
    EventHandler是一个类, 内部有委托的Array集合,但本身不是。所以,当用+=,-=对Array中的委托做维护时, .net会重新构造这个实例。导致其引用地址发生变化。
    这点,有点类似于 string 类型。如:
    string a = "a";
    string b = "b";
    string ab = a + b;
    string ab1 = "ab";
    string tmp = a;tmp += "d";
    MessageBox((a == tmp).ToString());
    MessageBox((ab.RefenceEqual(ab1)).ToString());
      

  5.   

    EventHandler是一个类
    -----------------
    是委托类型。
      

  6.   

    EventHandler<MyEventArgs> temp = SampleEvent;
    if (temp != null)
        temp(this, new MyEventArgs(val));
    ==================
    C#会对事件和委托的"="操作进行特殊处理,不仅仅是传递一个引用,而是把SampleEvent的订阅方法列表复制一份。
    所以执行完第一句后,就算有另外一个线程把SampleEvent里的处理方法"-="空了,第三句也不会有空异常。