Friday, March 07, 2008

C# WTF: Abuse of events

Someone actually noticed my last post, so I'm going to start putting more of that stuff on here.

Getting a property through events:

Common uses:

  • Pretending to decouple classes for no apparent reason.



public delegate int GetSomeValueDelegate();

 

class Foo

{

    public event GetSomeValueDelegate GetSomeValue;

 

    public void DoStuff()

    {

        /* . . . */

        if (this.GetSomeValue != null && this.GetSomeValue > 4)

        {

            OtherStuff();

        }

        /* . . . */

    }

}

 

class Bar

{

    private Foo foo;

    private int someValue;

 

    public Bar()

    {

        foo = new Foo();

        foo.GetSomeValue += new GetSomeValueDelegate(this.HandleGetSomeValue);

    }

 

    public void Run()

    {

        foo.DoStuff();

    }

 

    private int HandleGetSomeValue()

    {

        return this.someValue;

    }

}



Common variants:

  • Having the event return a reference to the Bar instance that manages Foo.

  • Having the event return a property of singleton that is accessible from both classes.





Externalizing logic through events
Common uses:

  • Decoupling a class from its internal logic.



public delegate void ResultsEventHandler(string[] results);

 

class Foo

{

    public event ResultsEventHandler ResultsEvent;

 

    private string[] resultsData;

 

    public string[] Results

    {

        get { return this.resultsData; }

        set { this.resultsData = value; }

    }

 

    public void DoStuff()

    {

        string[] results = PerformOperation();

        if (ResultsEvent != null)

        {

            ResultsEvent(results);

        }

    }

}

 

class FooManager

{

    private Foo foo;

    private Bar bar;

 

    public FooManager()

    {

        foo = new Foo();

        bar = new Bar();

        foo.ResultsEvent += new ResultsEventHandler(this.OnResultsEvent);

    }

 

    public void DoStuff()

    {

        foo.DoStuff();

        ProcessResults(foo.Results);

    }

 

    private void OnResultsEvent(string[] results)

    {

        foo.Results = results;

        bar.Data = results;

    }

}