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;

    }

}

Thursday, January 03, 2008

C# WTF: Abuse of exception handlers

I've started collecting assorted examples of bad code, and will start periodically posting them. Everything seen here was first seen in real code (and fixed, when possible). Just remember, these are examples of what you shouldn't ever do! :-)

Type checking by InvalidCastException:

Common uses:
  • Checking the type of an object in a collection when the developer does not know about the "is" operator or its equivalents.


Selection selItems = UtilServices.GetInstance().GetSelectedItems();

if (selItems != null)

{

    try

    {

        foreach (object item in selItems)

        {

            // Cast to a Foo Item.

            FooItem fooItem = (FooItem)item;

        }

        ProcessSuccess();

    }

    catch (System.Exception ex)

    {

        // If an exception is thrown, the items are not FooItems

        Logger.Error("Exception: " + ex.Message);

        ProcessFailure();

    }

}



Null checking by Exception handler:

Common uses:
  • Not being bothered by the hassle of all those "if" statements.


try

{

    foo = bar.GetSomeData();

    thing = foo.ThingValue;

}

catch

{

    foo = bar.GetOtherData();

    thing = foo.ThingValue;

}