Feeds:
Posts
Comments

Archive for May, 2009

Continuing on from my previous blog entry, in this entry I will talk about variant generic delegates. Just as with generic interfaces, generic delegates can use out and in to specify covariant and contravariant parameters respectively. And the MSIL equivalents are the + and - symbols.

Here are three variant generic delegate declarations:

delegate T CovariantDelegate<out T>();
delegate void ContraVariantDelegate<in T>(T t);
delegate T1 ContraAndCovariantDelegate<out T1, in T2>(T2 t2);

The rules are the same as with generic interfaces. The covariant delegate can only use the generic parameter as a return type, while the contravariant delegate can only use it as a delegate argument and not as a return type. The third delegate is both covariant and contravariant but with respect to two separate parameters. And here’s how these delegates can be used:

static Derived SomeFunc()
{
    return new Derived();
}

static void SomeOtherFunc(Base b)
{
}

static Derived AnotherFunc(Base b)
{
    return new Derived();
}

private void DoDelegates()
{
    CovariantDelegate<Base> covariantDeleg = SomeFunc; <--(#1)

    ContraVariantDelegate<Derived> contraDeleg = SomeOtherFunc; <--(#2)

    ContraAndCovariantDelegate<Base, Derived> contraCovarDeleg = AnotherFunc; <--(#3)
}

(#1) : Covariance at play here. Even though SomeFunc returns a Derived type, we use it to instantiate a delegate that expects a Base type.

(#2) : Contravariance here. The delegate expects a Derived argument, but we pass it a method that takes a Base argument.

(#3) : This is essentially a mix of (#1) and (#2).

Here’s a more realistic use of variance in generic delegates:

class Item
{
    . . .

    public int Code { get; set; }
}

class Book : Item
{
    public string Title { get; set; }
}

class DVD : Item
{
    public string Description { get; set; }

    public int Duration { get; set; }
}

Item FindItem(string searchText, Func<string, Item> findFunc)
{
    return findFunc(searchText);
}

Notice how the FindItem method’s second parameter is a Func<> object that itself takes a string and returns an Item. Func‘s return type parameter is covariant, and that’s what we can take advantage of. The code below shows two methods, one that searches for a book, and the other that searches for a DVD.

static List<Book> books = < . . . >

static Book FindBook(string searchText)
{
    return books.FirstOrDefault(book => book.Title == searchText);
}

static List<DVD> dvds = < . . . >

static DVD FindDVD(string searchText)
{
    return dvds.FirstOrDefault(dvd =>
        dvd.Description.StartsWith(searchText)
        || searchText.Contains(dvd.Duration.ToString()));
}

The following code shows how to call FindItem using a delegate of our choice.

Item book = FindItem("C++/CLI in Action", FindBook);

Item dvd = FindItem("Batman", FindDVD);

In the first call, we pass a method that returns a Book, whereas the method signature expects a method that returns an Item. But since Func<>‘s return parameter is covariant, this works fine. Essentially we are passing a Func<string, Book> as a Func<string, Item> argument. It’s the same for the second call too except that we have a DVD instead of a Book.

Now let’s see a contravariant delegate example. Consider the following method:

void ShowItemCode<T>(T item, Action<T> showFunc)
{
    showFunc(item);
}

It takes an Action<T> as the second argument which is a contravariant generic delegate. Now consider the following code:

static void ShowCode(Item item)
{
    Console.WriteLine(item.Code);
}

. . .

Book book = < initialize here . . .>
ShowItemCode(book, ShowCode);

DVD dvd = < initialize here . . .>
ShowItemCode(dvd, ShowCode);

In the first case we are calling ShowItemCode<Book> which expects Action<Book> as the second argument. But we pass ShowCode(Item) which matches Action<Item> yet it works because Action<> is contravariant.

Remember how in the previous entry I had mentioned a case where a covariant parameter type can be used as the parameter type for a contravariant delegate argument? Well, here’s an example of that:

interface ITestCovariant<out T>
{
    //void Bar(T t); <-- won't compile
    void Foo1(Action<T> func);
    void Foo2(Func<T, bool> func);
}

Even though T is a covariant parameter, we can use it as the parameter type for Action<> since Action is contravariant. I have also used it as the first type argument for the Func<> argument because though Func<> has a covariant return type, it’s input argument generic types are contravariant. Similarly for a contravariant interface:

interface ITestContravariant<in T>
{
    //T Bar(); <-- won't compile
    Func<T, bool> Foo1();
    Action<T> Foo2();
}

Here, we have a contravariant parameter T, but we’ve indirectly used it in the return type by using it to set the contravariant parameters in the Func<> and Action<> delegates.

Read Full Post »

The CLI supports variant generic parameters for interfaces as well as delegates, and C# 4.0 has added support for that. In this blog entry I’ll talk a little about variance in generic interfaces, and in a later entry I will talk about variance in delegates.

Covariance allows you to use a more derived type than what’s specified by the generic parameter, whereas contravariance allows you to use a less derived type. Generic interfaces can be covariant, contravariant, or both (though not for the same parameter).

Consider the following code:

class Base
{
}

class Derived : Base
{
}

interface ICovariant<out T> <-- covariant parameter
{
}

class Covariant<T> : ICovariant<T>
{
}

interface IContraVariant<in T> <-- contravariant parameter
{
}

class ContraVariant<T> : IContraVariant<T>
{
}

There’s a base class and a derived class, a covariant interface, an implementation of that interface, a contravariant interface, and its implementation. In C# a covariant parameter is prefixed with out, and a contravariant parameter is prefixed with in. In MSIL the symbols + and - are used for covariance and contravariance. (Note : at the time of writing, Reflector does not recognize or show variant generic parameters, but ildasm does show it correctly).

Here’s some code that shows the variance in action:

ICovariant<Base> baseCov = new Covariant<Base>();
ICovariant<Derived> derivedCov = new Covariant<Derived>();
baseCov = derivedCov; <-- covariance

IContraVariant<Base> baseContra = new ContraVariant<Base>();
IContraVariant<Derived> derivedContra = new ContraVariant<Derived>();
derivedContra = baseContra; <--contravariance

In the first case, we were able to assign a more derived generic instantiation to be assigned to a less derived one. In the second case we did the exact opposite. The Base Class Library has been updated to support covariance and contravariance in various commonly used interfaces. For example, IEnumerable<T> is now a covariant interface – IEnumerable<out T>. This lets us do:

IEnumerable<object> objects = new List<string>();
IEnumerable<Base> baseList = new List<Derived>();

That was something you could not do prior to C# 4.0. Now you won’t have to use LINQ’s Cast<>() as often as you may doing now. There are some rules to follow when using variant generic parameters.

For covariant generic parameters, the generic parameter can only be a return type, it cannot be used as a method argument. It also cannot be used as a generic constraint. (Note : A contravariant delegate can be used as a method parameter that uses the generic parameter as its generic parameter type. I’ll talk about it in my entry on variant delegates)

For contravariant generic parameters, the rules are basically reversed. The parameter type can only be a method argument or a generic type constraint, it cannot be used as a return type. Here’s an interface that has both contravariant and covariant generic parameters.

interface IContraAndCovariant<in T1, out T2>
{
    //T1 Foo(T2 value); <-- won't compile

    T2 Foo(T1 value);
}

Here’s a more realistic example of where covariance comes in very handy:

class Item
{
    public void CheckOut()
    {
        Console.WriteLine("{0} checked out", Code);
    }

    public int Code { get; set; }
}

class Book : Item
{
    public string Title { get; set; }
}

static void CheckOutItem(IEnumerable<Item> source, int code)
{
    try
    {
        source.First(item => item.Code == code).CheckOut();
    }
    catch (InvalidOperationException ex)
    {
        Debug.WriteLine(ex.Message); // invalid code
    }
}

CheckOutItem expects an IEnumerable of Item elements, but because IEnumerable<T> is covariant, I can do this:

List<Book> books = new List<Book>()
{
    new Book(){Code = 99, Title = "C++/CLI in Action"},
    new Book(){Code = 101, Title = "Ajax in Action"},
    new Book(){Code = 105, Title = "ASP.NET Ajax in Action"},
};

CheckOutItem(books, 99);

I have passed an IEnumerable<Book> to a method where an IEnumerable<Item> was expected. And here’s a realistic example of where contravariance can be used:

class ItemComparer : IComparer<Item>
{
    public int Compare(Item x, Item y)
    {
        return x.Code.CompareTo(y.Code);
    }
}

private void ContravarianceTest()
{
    List<Book> books = new List<Book>()
    {
        new Book(){Code = 199, Title = "C++/CLI in Action"},
        new Book(){Code = 501, Title = "Ajax in Action"},
        new Book(){Code = 105, Title = "ASP.NET Ajax in Action"},
    };

    books.Sort(new ItemComparer());
}

I used the List<T>.Sort overload that takes an IComparer<T> argument which in this case would have been an IComparer<Book> but since IComparer<T> is contravariant with regard to T, I could pass my ItemComparer class which is actually an IComparer<Item>.

Funnily, now that it’s available it’s kind of hard to think of how people managed to go without this all these years. It’s more the sort of feature that gets a “woah, we didn’t have this before!” response from people. In a later entry I will discuss variance in delegates.

Read Full Post »

One commonly heard grievance about C# was how it did not support optional parameters. Well C# 4.0 not only has that, but you can also specify parameters by name.

Consider the following two examples :

public void RepeatText(string text, int count = 3)
{
    while (count-- > 0)
    {
        Console.WriteLine(text);
    }

    Console.WriteLine();
}

public void RepeatDecoratedText(string text, string decoration = "Mr.", int count = 3)
{
    while (count-- > 0)
    {
        Console.WriteLine("{0} {1}", decoration, text);
    }

    Console.WriteLine();
}

RepeatText has an optional parameter count with a default value of 3, while RepeatDecoratedText has two optional parameters. The MSIL generated for these methods are as follows (simplified, and not exact) :

.method public void RepeatText(string text, [opt] int32 count)
{
    .param [2] = int32(3)

.method public void RepeatDecoratedText(string text, [opt] string decoration, [opt] int32 count)
{
    .param [2] = string('Mr.')
    .param [3] = int32(3)

[opt] is a parameter attribute that indicates that this parameter is optional and that the default value will be specified by .param entries. These methods can now be called as follows:

RepeatText("Nish");
RepeatText("Ant", 2); 

The compiler generates code with the optional values filled in as needed:

RepeatText("Nish", 3); <-- 2nd param set via .param value
RepeatText("Ant", 2); <-- No extra work needed

You can also now pass an argument by name. This is particularly useful when you want to skip some optional args, but provide others.

RepeatDecoratedText("Nish", count: 2);
RepeatDecoratedText(count: 2, text: "Ant");
RepeatDecoratedText(decoration: "The super", count: 2, text: "Ant");

That gets compiled as:

RepeatDecoratedText("Nish", "Mr." 2);
RepeatDecoratedText("Ant", "Mr.", 2);
RepeatDecoratedText("Ant", "The Super", 2);

So basically, the parameters are either filled in via the named values provided or via the default optional values. Note that you can write optional value methods using attributes too. Example:

public void RepeatTextDuplicate(string text, [Optional, DefaultParameterValue(3)] int count)
{
    RepeatText(text, count);
}

// . . .

RepeatTextDuplicate("Nish");
RepeatTextDuplicate("Nishant", 5);

The MSIL generated for this method is identical to what you’d have got with the direct C# syntax (used earlier).

As with dynamic types, apparently the biggest beneficiaries of these new named and optional parameter features are developers who interop with Office. Just like in VBScript you can now avoid having to provide optional arguments, and can also provide a named argument directly. For others, optional parameters will definitely help reduce the number of method overloads you need to write, and where there are methods that have more than a few optional parameters, the ability to call them by specifying named parameters will result in cleaner and more legible code.

Read Full Post »

VS 2010 Beta 1 includes some C# 4.0 features and though I have been reading about some of the new stuff on various blogs and forums, I only got to play with it very recently. Put simply, the dynamic keyword allows you to declare and use types that are not type-checked during compilation. They are resolved at runtime using the DLR.

Here’s a simple class that has a dynamic field, a method that has a dynamic argument, and a dynamic property:

class Dynamic
{
    private dynamic data;

    public void SetData(dynamic data)
    {
        this.data = data;
    }

    public dynamic MetaData { get; set; }

    public void Display()
    {
        Console.WriteLine("{0} {1}, {2} {3}",
            data, data.GetType(), MetaData, MetaData.GetType());
    }
}

Using the class is quite straightforward:

private void Foo()
{
    var d = new Dynamic();
    d.MetaData = 100; <-- Int32
    d.SetData(99); <-- Int32
    d.Display();
    d.MetaData = 100f; <-- Single
    d.SetData("hello"); <-- String
    d.Display();
}

Notice how I keep using different types at runtime for calling the same methods and properties. If you look at the IL via Reflector, you’ll see that dynamic types are internally treated as System.Object. Intellisense within VS 2010 will also give you System.Object members since that’s what they are guaranteed to have.

There are three dynamic calls in the Display method. A nested static class is generated inside the Dynamic class, and it will have one static CallSite<> field per dynamic call. In this case, there are three such fields. Whenever the dynamic calls are made, it’s these DLR call sites that come into play. An extremely simplified explanation of what happens is that the DLR internally uses reflection to figure out what type the dynamic object is at runtime. There is also caching done so that type-matching (or mapping) is not repeated unnecessarily. Of course the implementation is quite complex and you could probably spend weeks going through the code in Reflector. Note that if you make dynamic calls in a different method, there will be another static class generated – so it seems to be one inner class per method.

Consider the following simple method:

public void Test()
{
    var type = data.GetType();
}

A class will be generated similar to the following (I’ve made this easy to read – so this is not an accurate representation of the generated code):

[CompilerGenerated]
private static class SiteContainerForTest
{
    public static CallSite<FUNC<CALLSITE, object, object>> callSiteGetType;
}

And the method Test gets compiled into:

public void Test()
{
    if (SiteContainerForTest.callSiteGetType == null)
    {
        SiteContainerForTest.callSiteGetType = CallSite<Func<CallSite, object, object>>.Create(
            new CSharpInvokeMemberBinder(
                CSharpCallFlags.None,
                "GetType", <-- the name of the dynamic member
                typeof(Dynamic),
                null,
                new CSharpArgumentInfo[] { new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }
            )
        );
    }

    object type = SiteContainerForTest.callSiteGetType.Target(
      SiteContainerForTest.callSiteGetType,
      this.data <-- the dynamic object
    );
}

The call site’s Target will be of type Func<CallSite, object, object>, and the return type is object (because at compile time that’s what the local variable type was defined as, since we don’t know what type it would be at that time). It’s at this point that dynamic binding is done. Fortunately for us, it’s all done behind the scenes and we are protected from having to write all this code ourselves. Assuming data is an Int32 at this time, Int32‘s GetType is called (and since it doesn’t have one, Object‘s GetType is invoked).

You can also use dynamic types locally (a site container class is generated for the containing method) :

dynamic d = 1;
string s = d.ToString();
Console.WriteLine(s);

d = "dynamic data";
Console.WriteLine(d.Length);

d = 33;

try
{
    int len = d.Length; <-- Invalid dynamic call on an Int32 object
}
catch (RuntimeBinderException ex)
{
    Console.WriteLine(ex.Message);
}

When I try to use the non-existent Length property on an Int32 value, the runtime will throw a RuntimeBinderException. And it even gives a very useful error message : ‘int’ does not contain a definition for ‘Length’.

Overall, one of the most celebrated uses of dynamic types is supposed to be for Office interop. You no longer have to do endless casts and mid-level variables for debugging. It’s just as easy as using classic VBScript. At this point, unless you want to interop with Word or Excel, I can’t think of too many scenarios where this will come in handy. Maybe someone who’s more functionally oriented than I am can think of some common scenarios.

Read Full Post »

Here’s another tip from an MSDN forum discussion. Someone wanted to know how to flush the keyboard buffer in a C# console application.

Here’s a simple hack to do this :

private static void FlushKeyboard()
{
    while (Console.In.Peek() != -1)
        Console.In.Read();
}

Now you can use it as follows :

char x = (char)Console.Read();
FlushKeyboard();
char y = (char)Console.Read();
Console.WriteLine("{0}, {1}", x, y);

Even if you enter more than a single character after the first call to Read(), the second Read() will not be affected.

Read Full Post »

A few weeks ago someone asked on the MSDN forums how he could use the mailto: protocol to send a multi-line email. The trick is to use %0D%0A in lieu of \r\n.

Here’s a small C# code snippet that shows how to do this :

string command = "mailto:abc@abc.com?subject=The Subject&body=Ln 1%0D%0ALn 2";
Process.Start(command);

Read Full Post »

Follow

Get every new post delivered to your Inbox.