Cottleston Pie

Fernando Felman’s thoughts on software development

Archive for the ‘Generics’ Category

Recursive Generics Restrictions

Posted by Fernando Felman on September 23, 2007

Here’s an interesting question for you, Generics gurus. Is the following is a valid definition for a generic class in c#?

public class Generic<T> where T : Generic<T>

On first glance it seems that the recursive restriction on type T cannot be possible. For example, if we would like to pass “string” as the type T we would have to wrap it with Generic<string> which in turn needs to be wrapped with Generic<Generic<string>> which in turns needs to be wrapped with Generic<Generic<Generic<string>>> and so on and so forth. But a closer examination reveals that this is actually a valid declaration.

The restrictions on the type T are used to ensure that the type we pass can be treated as the restricted type. In other words, whatever type T we chose to pass, the compiler should be able to cast it to the form Generic<T>. In our case, any class that derives from Generic<T> responds to the restriction and can be used. To conclude, the restrictions on the class Generic<T> defined above ensures that the passed type T is derived from itself (from Generic<T>). For example, the following is a valid class to pass as T:

public class ValidClass : Generic<ValidClass>

 

When can this be used? The recursive restriction shown here can be useful for factories, in which you want to define some basic logic and return a well known type. Consider the following example:

Generic Factory with Recursive Restriction

Using the recursive restriction of Generics we can enforce type affinity to the Employee factory.

Posted in Generics | 3 Comments »

Multiple Generics restrictions in VB.NET

Posted by Fernando Felman on July 17, 2007

Did you know that VB.NET accept curly brackets ({ })? Neither did I, but it does for the special case of multiple restrictions describing a Generics type.

I needed to code a web service factory, and I used Generics to do so. In C#, the code would look like this:

Generics web service factory in C#

The Generic type T has multiple restrictions: it derives from the base web service proxy and it implements a default constructor. Easy. But the project using this will be a VB.NET, and I’d prefer to have this factory in the same language. So, after some digging, here’s the same factory implemented in VB.NET:

Generics web service factory in VB.NET

Seams to me that the multiple restrictions notation in VB is very much like an in-line array initiation in C#. I think some C# developer suggested this syntax – it’s just so not VB like…

Posted in .Net v2, Generics | 1 Comment »

Variance and Generalized Constraints, MS Research Publications

Posted by Fernando Felman on March 4, 2007

A very good document with recommendation for Variance and Generalized Constraints implementation in C# by Burak Emir, Andrew J. Kennedy, Claudio Russo, and Dachuan Yu.

Let me just quote the Introduction so you can understand what it is all about:

The Generics feature of C# 2.0 introduced parametric polymorphism to the language, supporting type parameterization for types (classes, interfaces, structs,and delegates) and methods (static and instance). Being object-oriented, C# already offers subtype polymorphism, namely the ability for a value of type T to be used in a context that expects type U, if T is a subtype of U.
As it stands, though, subtype and parametric polymorphism interact only through subclassing. In particular, there is no subtyping relationship between distinct instantiations of the same generic type type parameters are said to behave invariantly with respect to subtyping. This leads to a certain inflexibility: a method whose parameter has type IEnumerable<Control>cannot be passed an argument of type IEnumerable<Button>,even though this is safe: since Button is a subclass of Control, something that enumerates Buttons also enumerates Controls. Dually, a method expecting a parameter of type IComparer<Button> cannot be passed an argument of type IComparer<Control>, even though this is safe: something that can compare Controls can also compare Buttons.

The document then details possible extensions to C# in order to express Variance and Generalized Constraints.

I hope MS will implement the recommendations since I already found myself dealing with this issue in the past and I’m not entirely happy with the workaround I used.

Posted in Generics | 1 Comment »

Using Generics to code type-free helpers

Posted by Fernando Felman on March 2, 2007

The other day I received a small WinForm application to review. The application uses many forms, each designed for a single-specific task. I noticed that in the main form, the developer duplicated the following code snipped to initiate various forms:

if ((this.frmUtil1 == null) || this.frmUtil1.IsDisposed)
{
    this.frmUtil1 = new Forms.Util1();
}
this.ShowForm(this.frmUtil1);

if ((this.frmUtil2 == null) || this.frmUtil2.IsDisposed)
{
    this.frmUtil2 = new Forms.Util2();
}
this.ShowForm(this.frmUtil2);

One of the best practices I found is that if you’re duplicating a code section, it’s a good indication of a shared functionality that can be encapsulated. We’d like to have a service that will receive an object representing the WinForm and handle it by properly initiating the form when required:

public void ShowForm(Form sourceForm, Form reusableForm);

In .Net 1.1 we must go through reflection in order to create an object of the correct class dynamically, but in .Net 2.0 we’ve got Generics to facilitate things:

static class FormHelper<T>
    where T : Form, new()
{
    public static void ShowForm
        (Form sourceForm, ref T reusableForm)
    {
        if (reusableForm == null || reusableForm.IsDisposed)
        {
            reusableForm = new T();
        }
        sourceForm.Show(reusableForm);
    }
}

Notice the usage of the new constraint after the description of the type T: this tells the compiler that the type T supports a default public constructor and so we can easily create a new object of the T class using new T();

To use the service you’d pass the type of the forms and both forms varibales:

FormHelper<Froms.Util1>.ShowForm(this, ref this.frmUtil1);

This would both initiate this.frmUtil1 with a new instalse of Froms.Util1 when needed and also show the form.

Posted in Generics | Leave a Comment »