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

时间:2015-06-01 09:55:38

标签: c# events callback delegates

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

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

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

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....
    }
}

编译时,代码分析给了我,&#34; CA1009:正确声明事件处理程序?&#34;而且我已经搜索过高低,发现了许多问题,文章等,但没有一个感觉它们符合我的情景。我似乎找不到转换的具体起点,我开始怀疑我是否打算完全改写实现?

编辑:首先,我非常感谢助攻,在发布此内容之前,我确实仔细查看了所有网站,并且我确实看到了(并尝试使用)您发布的每个链接。我甚至回去再次研究代表和活动,但我觉得我错过了起点,因为每次我尝试更改它的一部分时,我只会继续产生我无法回复的错误像:

public delegate void TestEventHandler( object sender, EventArgs e );

通过我访问过的其他链接,我只能找到与我的代码有1个相似之处(在委托,处理程序或属性中),但是找不到任何足够相关的东西来实际灌输&# 34;尤里卡&#34;矩

编辑2:我现在用'#34;看起来&#34;重建了我的例子。要成为正确的标准,但是这段代码非常难看,它看起来像是被一个混合棒殴打并蘸了一罐有点狡猾的坦克,然后被油炸成了极好的东西:

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....
    }
}

请告诉我,我错过了一些事情,实际上有更优雅的实施

编辑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;
    }
}
  1. 这会被认为是好的代码还是我应该使用Enigmativity代码中定义的OnTestHappening方法?
  2. 为什么我不能使用无参数代理?它现在使用的是默认的( object sender, EventArgs e ),但这感觉有些过分并且没有理由为什么编译器对它感到满意但是根据编码标准,它被认为是错误的代码?我不是在争论标准,而是试图理解它的推理。

1 个答案:

答案 0 :(得分:2)

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

def handler_akif_room(type, source, parameters):
        room = parameters
        if parameters.split():
        iq = xmpp.Iq('set')
        iq.setID('Nimbuzz_SearchRooms')
                iq.setTo('conference.nimbuzz.com')
                query = xmpp.Node('query') 
                query.setNamespace('jabber:iq:search')
                iq.addChild(node=query) 

                sett = xmpp.Node('set')
                sett.setNamespace('http://jabber.org/protocol/rsm')
                query.addChild(node=sett)

                sifir = "0"
                ind = xmpp.Node('index')
                ind.setData(sifir)
                sett.addChild(node=ind)

                on = "10"
                maxx = xmpp.Node('max')
                maxx.setData(on)
                sett.addChild(node=maxx)

                qqx = xmpp.Node('x')
                qqx.setNamespace('jabber:x:data" type="get')
                query.addChild(node=qqx)

                field = xmpp.Node('field')
                field.setAttr('var','name')
                field.setData(' ') 
                qqx.addChild(node=field)

                valueone = xmpp.Node('value')
                valueone.setData(room)
                field.addChild(node=valueone)



                fieldtwo = xmpp.Node('field')
                fieldtwo.setAttr('var','include_password_protected')
                fieldtwo.setData(' ')
                qqx.addChild(node=fieldtwo)

                valuetwo = xmpp.Node('value')
                valuetwo.setData('true')
                fieldtwo.addChild(node=valuetwo)


        JCON.SendAndCallForResponse(iq, handler_akif_room_answ, {'type': type, 'source': source})
        msg(source[1], u''+str(iq)+' .') ## <= OUT SHOW :)) GOOD WORK! CONTACT ME akif@nimbuzz.com :)

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); } } 看起来像这样:

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

运行此输出var tester = new Tester(); tester.Main(); 到控制台。

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

True