Peet Brits

Hmm, but that doesn't make any sense…

Posts Tagged ‘C#’

Introduction to C# Delegates and Events

Posted by Peet Brits on August 3, 2010

Delegate: A person appointed or elected to represent others.

In programming a delegate, or a method definition or a function pointer, represents a reference or pointer to a method. In C++ it had many confusing stars and brackets, but in C# the definition is rather simple:

// Delegate / method definition
public delegate void NodeEvent(object sender, bool reloadOnly);

The second concept related to delegates is Events. Events conform to the definition of the delegate. Any code can use a delegate, but only the containing class can throw events. This provides an easy construct for external code to subscribe to and unsubscribe from events.

// Event definition, conforming the the delegate "NodeEvent"
public event NodeEvent BeforeExpandNode;

// SUBSCRIBE SAMPLE (this happens in the client code)

listBrowser.BeforeExpandNode += new NodeEvent(listBrowser_BeforeExpandNode);

// TIP: in VS, when you type '+=' and press tab, the designer
// will automatically generate the method definition

// The definition of this method is the same as the delegate "NodeEvent"
void listBrowser_BeforeExpandNode(object sender, bool reloadOnly)
{
    // ...
}

// Optionally, you can add/remove methods in a much simpler way:
listBrowser.BeforeExpandNode += listBrowser_BeforeExpandNode;   // Add (subscribe)
listBrowser.BeforeExpandNode -= listBrowser_BeforeExpandNode;   // Remove (unsubscribe)

The above same shows how events allow you to call a list of methods at once by calling the single method “listBrowser.BeforeExpandNode.” The attached methods will trigger in the order that they were attached. It is the client’s responsibility to ensure that the called methods are exception safe. If the attached method throws an exception then the entire list will be abandoned.

// THROW EVENT SAMPLE (this happens in the class where the event is defined)

protected void OnBeforeExpandNode(object sender, bool reloadOnly)
{
    // I am lazy to type this out every time, so I put it in a method.
    // In programming, lazy usually means efficient.

    // Private variable to ensure thread safety
    var handler = BeforeExpandNode;
    if (handler != null)
    {
        // This will call everything subscribed to it.
        // In our example this is "listBrowser_BeforeExpandNode()"
        handler(sender, reloadOnly);
    }
}

// Usage sample:
private void ExpandNode()
{
    // Add custom checks here
    // ...

    // Now raise the "BeforeExpandNode" event
    OnBeforeExpandNode(this, false);

    // Now continue to expand the node
    // ...
}

Comparing the two, you can only invoke events from with the declared class, but any class can use delegates. Interfaces can specify events, but not delegates. Events can override Add/Remove method accessors. For more differences, see this comparison between delegates and events.

That is it! Now you know how to use basic delegates and events. As a bonus, here is an additional sample:

// When registering an event it is possible to use a delegate instead of the actual method.
// I prefer to avoid this, because it makes debugging much harder.
btn.Click += delegate(object sender, RoutedEventArgs e) { ... };
Advertisements

Posted in Code (Programming) | Tagged: , , , , | Leave a Comment »

Writing IT Documentation

Posted by Peet Brits on November 10, 2009

How many programmers would agree that there is a lot of useless IT documentation out there, mostly because they state the obvious. Microsoft documentation is often very guilty of this. For example, is the phrase “creates a new XML Node” really a good definition for “XmlNode”?

I am not here to rand and rave about problems, but rather to suggest possible solutions. There is a long forgotten rule that I would like to point out:

Rule: Do not use the defined word inside its definition.

Most definitions stating the obvious is guilty of breaking this rule. Let me go back to my “XmlNode” example from earlier. Instead of stating the obvious, which everybody already knows, most people reading the documentation would probably want to know the difference between “XmlNode” and “XmlElement”. Here is a hint for applying the rule: Begin your sentence with “An XmlNode is a <…>”.

I know most programmers would rather eat their hat than write documentation, but when you absolutely have to do something, at least do a decent job at it! I hope this post will set the right mindset for writing better documentation.

Posted in Code (Programming) | Tagged: , , , , | Leave a Comment »

LINQ: Breaking Your Logic

Posted by Peet Brits on October 18, 2008

LINQ is one of the great new technologies in .NET. As opposed to the frustrations of raw text in XML, I absolutely love how it is strongly typed. I am not going to spend any time discussing its use and features, as there is enough of that on the internet. Instead I will discuss some unexpected behaviours that I recently uncovered.

Without wasting the reader’s time, let me jump straight to the problem. Here is a sample of the filter I would like to apply:

var docs = from doc in db.GetTable()
    where doc.Name == interfaceName
    && (filter.Failed.HasValue && doc.Failed.HasValue &&
        filter.Failed.Value == doc.Failed.Value)
    orderby doc.Name
    select doc;

Background: “Failed” is a Nullable bit value both in the code and in the database. I only want to compare and filter if a values has been provided.

This seems like a perfectly acceptable piece of code. The expected C# behaviour for “&&” is that when the first section fails, the following section will not even be evaluated, and therefore it must surely work.

So I thought.

On executing the statement I got the exception “Nullable object must have a value”, originating from line 4 above. I remembered that LINQ translates its logical items to a form of expression tree, so it would seem that all values are always evaluated, regardless of the expected C# behaviour. We need to get rid of “Failed.HasValue”.

No problem, update the filter:

var docs = from doc in db.GetTable()
    where doc.Name == interfaceName
    && (filter.Failed.HasValue && doc.Failed.HasValue &&
        filter.Failed == doc.Failed)
    orderby doc.Name
    select doc;

No exception, the query runs through. Only one problem, my result set is empty.

So I evaluate my code again. The first problem is that the query section “filter.Failed == doc.Failed” on line 4 is always evaluated, regardless of whether the first two statements are false.

If that is not enough there is a second problem, regarding what happens when filtering. Once again, take a look at line 4. As it is always evaluated, it would seem that when the filter condition is “null” it evaluates to “null == doc.Failed”, where “doc.Failed” can be true, false, or DBNull.Value. This is clearly not right.

Where to from here? Writing C# functions inside the match is not the answer, as you need to implement translations supported by SQL for the specific section.

The quick and dirty answer is as follows:

// Why not use var?  Because the return type keeps changing.
IQueryable docs = from doc in db.GetTable()
    where doc.Name == interfaceName
    select doc;

if (filter.Failed.HasValue)
    docs = from doc in docs
        where filter.Failed == doc.Failed
        select doc;

// more filter blocks here

// Finally, remember to sort.
docs = from doc in docs
    orderby doc.Name
    select doc;

This works fine, but as one might have more than one item to filter on this process might result in a lot of code that needs to be duplicated all over the place. The statement “doc.Failed.HasValue” is also not evaluated, but that is something that can be safely ignored.

On the Microsoft webpage at http://msdn.microsoft.com/en-us/library/bb882535.aspx they give the following advice for handling null values (thanks to Marius for providing the link):

// When the parent item might be null,
// the "?:" syntax is not converted to query trees.
(p == null ? null : p.CategoryID)

// When comparing nullable DB values to non-nullable objects,
// box it in a nullable container.
o.EmployeeID equals (int?)e.EmployeeID

That being said, the final product looks as follows:

IQueryable docs = from doc in db.GetTable()
    where doc.Name == interfaceName
    select doc;

if (filter != null)
{
    docs = from doc in docs
        where (filter.Failed.HasValue ? filter.Failed == doc.Failed : true)
        // && (...) -- more filters here
        select doc;
}

// Finally, remember to sort.
docs = from doc in docs
    orderby doc.Name
    select doc;

[Edit: Just for fun I created a follow-up quiz for this article.]

Posted in Code (Programming) | Tagged: , , , | 1 Comment »