正确声明回调事件处理程序

Sto*_*orm 0 c# events delegates callback

我有一个简单的委托、事件和属性,允许我在事件上创建回调订阅:

public static class Test
{
    /// <summary>Delegate for property changed event</summary>
    public delegate void TestEventHandler();

    /// <summary>Event called when value is changed</summary>
    public static event TestEventHandler OnTestHappening;

    /// <summary>Property to specify our test is happening</summary>
    private static bool testHappening;
    public static bool TestHappening
    {
        get
        {
            return testHappening;
        }
        set
        {
            testHappening = value;

            // Notify our value has changed only if True
            // ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
            if ( value )
            {
                if ( OnTestHappening != null )
                    OnTestHappening();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以轻松地订阅和取消订阅事件并根据需要触发事件回调:

public class Tester
{
    private void Main()
    {
        Testing();

        // Start the test
        Test.TestHappening = true;
    }

    private void Testing()
    {
        // Unsubscribe from event
        Test.OnTestHappening -= Testing;

        // Check if we're busy testing yet
        if ( !Test.TestHappening )
        {
            // Subscribe to event
            Test.OnTestHappening += new Test.TestEventHandler( Testing );

            return;
        }

        // Do stuff here....
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时,代码分析给我,“CA1009:正确声明事件处理程序?” 我搜索了很多,发现了很多问题、文章等,但没有一个能解决我的情况。我似乎找不到转换的具体起点,我开始怀疑我是否打算完全重写实现?

编辑:首先,我非常感谢这些帮助,在发布之前我确实仔细浏览了所有我能找到的网站,我确实看到(并尝试使用)你们发布的每个链接。我什至回去重新研究了委托和事件,但我觉得我不知何故错过了起点,因为每次我尝试更改其中的一部分时,我只是不断地产生我无法回来的错误,例如:

public delegate void TestEventHandler( object sender, EventArgs e );
Run Code Online (Sandbox Code Playgroud)

通过我访问的其他链接,我只能找到与我的代码(在委托、处理程序或属性中)有 1 个相似之处,但找不到任何与我的代码相关的内容,无法真正灌输“尤里卡”时刻

编辑 2:我现在用“看起来”是正确的标准重新构建了我的示例,但是这段代码太模糊了,看起来像是用 confogulus 棒殴打并浸入一罐 confutious 中,然后被炸成可怕的:

public static class Test
{
    /// <summary>Delegate for property changed event</summary>
    public delegate void TestEventHandler( object sender, EventArgs e );

    /// <summary>Event called when value is changed</summary>
    public static event TestEventHandler OnTestHappening;

    /// <summary>Property to specify our test is happening</summary>
    private static bool testHappening;
    public static bool TestHappening
    {
        get
        {
            return testHappening;
        }
        set
        {
            testHappening = value;

            // Notify our value has changed only if True
            // ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
            if ( value )
            {
                if ( OnTestHappening != null )
                    OnTestHappening( null, EventArgs.Empty );
            }
        }
    }
}

public class Tester
{
    private void Main()
    {
        Testing( this, EventArgs.Empty );

        // Start the test
        Test.TestHappening = true;
    }

    private void Testing( object sender, EventArgs e )
    {
        // Unsubscribe from the event
        Test.OnTestHappening -= Testing;

        // Check if we're busy testing yet
        if ( !GlobalClass.SystemOnline )
        {
            // Subscribe to the event
            Test.OnTestHappening += new Test.TestEventHandler( Testing );

            return;
        }

        // Do stuff here....
    }
}
Run Code Online (Sandbox Code Playgroud)

请告诉我我错过了一些东西,实际上有一个更优雅的实现

编辑 3:基于 Enigmativity 的代码,我将代码改写为最基本的形式。我还移动了以不同方法将变量设置为 true 的代码,因此它看起来不那么愚蠢Main

public static class Test4
{
    /// <summary>Event called when value is changed</summary>
    public static event EventHandler TestHappening;

    /// <summary>Property to specify our test is happening</summary>
    private static bool test = false;
    public static bool Test
    {
        get
        {
            return test;
        }
        set
        {
            // Notify our value has changed only if True
            // ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
            if ( value )
            {
                TestHappening( null, EventArgs.Empty );
            }
        }
    }
}

public class Tester4
{
    private void Main()
    {
        Testing( this, EventArgs.Empty );
    }

    private void Testing( object sender, EventArgs e )
    {
        // Unsubscribe from the event
        Test4.TestHappening -= Testing;

        // Check if we're busy testing yet
        if ( !Test4.Test )
        {
            // Subscribe to the event
            Test4.TestHappening += Testing;

            return;
        }

        // Do stuff here....
    }

    private void SomeMethodCalledFromSomewhere()
    {
        // Set the value to true and thereby start the test
        Test4.Test = true;
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 这会被认为是好的代码还是我应该拥有OnTestHappeningEnigmativity 代码中定义的方法?
  2. 为什么我不能使用无参数委托?它现在使用默认值,( object sender, EventArgs e )但这感觉有点过分,而且编译器对它感到满意也没有意义,但根据编码标准,它被认为是坏代码?我不是在争论标准,而是试图理解它的推理。

Eni*_*ity 5

根据 Storm 的要求,以下是我最有可能构建代码的方式。它更符合标准约定。

public static class TestClass
{
    public delegate void TestEventHandler(object sender, EventArgs e);

    public static event TestEventHandler TestHappening;

    private static bool test = false;
    public static bool Test
    {
        get
        {
            return test;
        }
        set
        {
            test = value;
            if (test)
            {
                OnTestHappening();
            }
        }
    }

    private static void OnTestHappening()
    {
        var handler = TestHappening;
        if (handler != null)
            handler(null, EventArgs.Empty);
    }
}
Run Code Online (Sandbox Code Playgroud)

而且Tester应该是这样的:

public class Tester
{
    public void Main()
    {
        TestClass.TestHappening += Testing;
        Go();
    }

    private void Testing(object sender, EventArgs e)
    {
        Console.WriteLine(TestClass.Test);
        TestClass.TestHappening -= Testing;
    }

    private void Go()
    {
        TestClass.Test = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

调用它看起来像这样:

var tester = new Tester();
tester.Main();
Run Code Online (Sandbox Code Playgroud)

将此输出运行True到控制台。


如果我用更标准的方式写这个,它看起来像这样:

public class TestEventArg : EventArgs
{
    public TestEventArg(bool updatedValue)
    {
        this.UpdatedValue = updatedValue;
    }
    public bool UpdatedValue { get; private set; }
}

public class TestClass
{
    public event EventHandler<TestEventArg> TestHappening;

    private bool test = false;
    public bool Test
    {
        get { return test; }
        set
        {
            var old = test;
            test = value;
            if (test != old)
                OnTestHappening(test);
        }
    }

    private void OnTestHappening(bool updatedValue)
    {
        var handler = TestHappening;
        if (handler != null)
            handler(this, new TestEventArg(updatedValue));
    }
}
Run Code Online (Sandbox Code Playgroud)