Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#.net中委托事件的超级简单示例?_C#_.net_C# 3.0 - Fatal编程技术网

c#.net中委托事件的超级简单示例?

c#.net中委托事件的超级简单示例?,c#,.net,c#-3.0,C#,.net,C# 3.0,我需要一个非常简单的例子来了解这些事件。我觉得很难理解internet或书籍中提供的例子。如果您有C背景,您可以将委托视为指向函数的指针。这是一个公开事件的类的简单实现 public class ChangeNotifier { // Local data private int num; // Ctor to assign data public ChangeNotifier(int number) { this.num = number; }

我需要一个非常简单的例子来了解这些事件。我觉得很难理解internet或书籍中提供的例子。

如果您有C背景,您可以将委托视为指向函数的指针。

这是一个公开事件的类的简单实现

public class ChangeNotifier
{
    // Local data
    private int num; 

    // Ctor to assign data
    public ChangeNotifier(int number) { this.num = number; } 

     // The event that can be subscribed to
    public event EventHandler NumberChanged;

    public int Number
    {
        get { return this.num; }
        set
        {
            // If the value has changed...
            if (this.num != value) 
            {
                // Assign the new value to private storage
                this.num = value;

                // And raise the event
                if (this.NumberChanged != null)
                    this.NumberChanged(this, EventArgs.Empty);
            }
        }
    }
}
此类可用于以下情况:

public void SomeMethod()
{
    ChangeNotifier notifier = new ChangeNotifier(10);

    // Subscribe to the event and output the number when it fires.
    notifier.NumberChanged += (s, e) => Console.Writeline(notifier.Number.ToString());

    notifier.Number = 10; // Does nothing, this is the same value
    notifier.Number = 20; // Outputs "20" because the event is raised and the lambda runs.
}
关于控制流,执行流入
SomeMethod()
。我们创建一个新的
ChangeNotifier
,并因此调用其构造函数。这将
10
的值分配给私有
num
成员

然后,我们使用
+=
语法订阅事件。该操作符在右侧接受一个委托(在我们的示例中,该委托是lambda),并将其添加到事件的委托集合中。此操作不执行我们在
ChangeNotifier
中编写的任何代码。如果愿意,可以通过事件上的
add
remove
方法对其进行自定义,但很少需要这样做

然后我们对
Number
属性执行几个简单的操作。首先,我们分配
10
,它在
Number
属性上运行
value=10
set
方法。但是
num
成员的值已经为
10
,因此初始条件的计算结果为false,并且不会发生任何事情

然后我们用
20
做同样的事情。这次值不同,因此我们将新值指定给
num
并触发事件。首先,我们验证事件是否为null。如果没有订阅,则为空。如果它不为null(即,如果有人订阅了它),我们将使用标准的方法/委托语法触发它。我们只是用事件的参数调用事件。这将调用订阅该事件的所有方法,包括执行
控制台.WriteLine()
的lambda


如果一个线程可以在
Number
的setter中,而另一个线程正在取消订阅侦听器,Henrik成功地发现了潜在的争用条件。我不认为对于那些还不了解事件如何运作的人来说,这是一个常见的情况,但是如果你担心这种可能性,那么修改以下几行:

if (this.NumberChanged != null)
    this.NumberChanged(this, EventArgs.Empty);
像这样:

var tmp = this.NumberChanged;
if (tmp != null)
    tmp(this, EventArgs.Empty);

代表不会是个问题。但对我来说,理解事件才是真正的问题。问题是关于事件。比赛条件!=null——行,因为如果您有更多的NumberChanged,则其他线程可以取消订阅。所有信息+1。抱歉,我是软件开发新手,但是编辑的3行代码与上面的2行代码有什么不同,后面3行代码中的“this”指的是什么,它将如何解决线程问题?请你详细说明一下好吗?谢谢假设初始条件有一个订阅此.NumberChanged的委托。线程A测试并发现事件不为null,然后线程B取消订阅该委托。然后线程A尝试执行(现在为空)事件。崩溃如果线程A首先将委托列表抓取到tmp中,程序将不再崩溃。这确实意味着委托可以在从事件中取消订阅后运行,因此事件处理程序委托必须对这种情况具有鲁棒性。
class Program
    {
        static void Main(string[] args)
        {
            Parent p = new Parent();
        }
    }

    ////////////////////////////////////////////

    public delegate void DelegateName(string data);

    class Child
    {
        public event DelegateName delegateName;

        public void call()
        {
            delegateName("Narottam");
        }
    }

    ///////////////////////////////////////////

    class Parent
    {
        public Parent()
        {
            Child c = new Child();
            c.delegateName += new DelegateName(print);
            //or like this
            //c.delegateName += print;
            c.call();
        }

        public void print(string name)
        {
            Console.WriteLine("yes we got the name : " + name);
        }
    }
Class A {
    public delegate void EventHandler();

    public static event EventHandler workComplete();

    void doWork(){
        // DO WORK  
    }

    void onWorkComplete(){
        // Raise event
        workComplete();
    }
}

Class Main {
    A a = new A();
    a.workComplete += new () -> {
        // On Class Complete Work
        Console.WriteLine("Work Complete");
    };
}