Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Note: This blog has moved to omervk.wordpress.com.

Omer van Kloeten's Facebook profile

Omer has been professionally developing applications over the past 8 years, both at the IDF’s IT corps and later at the Sela Technology Center, but has had the programming bug ever since he can remember himself.
As a senior developer at NuConomy, a leading web analytics and advertising startup, he leads a wide range of technologies for its flagship products.

Get Firefox


powered by Dapper 

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

October 2007 - Posts

Generic Parameter Inference
public static void Do<T>(this TBase value) where T : BaseClass<TBase>

The above line of code does not compile. I've been mulling over this for about half an hour and have not come up with a single logical reason why it shouldn't, strong-typing wise, except that it doesn't.

I can understand why using Type Inference (calling the method without the generic parameter), you could never bind to one predetermined T - after all, there may be an infinite amount of types that derive from BaseClass<TBase> and that's just when using TBase's topmost level of inheritance.

However, using a call to Do with the T generic parameter explicitly stated, there can be only one option for TBase, since:

  1. It is a class and you can never derive twice from the same type in your line of inheritance, so there's no fearing that T would derive from both BaseClass<A> and BaseClass<B> somewhere along that line.
  2. It is not an interface, where you could implement both ISomething<A> and ISomething<B>

Does anyone have any ideas?

ObservableCollection<T>.CollectionChanged Caveat

DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.

Users of collection properties often assume that the following code will always work:

IEnumerable<string> list = GetList();
foreach (string name in list)
{
    ...
}

The general rule is that null and empty (0 item) collections or arrays should be treated the same.

- Framework Design Guidelines, p. 217.

System.Collections.ObjectModel.ObservableCollection<T>'s event CollectionChanged uses the NotifyCollectionChangedEventArgs event arguments class, which holds two lists: OldValue and NewValue. When either is empty, it will be raised with a null as the list's reference.

I hope they fix this for the next release.

Fallback Values for Backwards Compatible Enums

Came up with a nice idea while driving today about versioning enums.

Say you have an application that saves files. Every file has a font specific to it and it is saved as the following enum (v1.0):

public enum Font
{
    Tahoma,
    Arial,
}

When v1.1 comes out, you want to be able to add a new value to the enum, for the font "Courier New". However, once you do that, you won't be able to open files that use it at all in v1.0.
This is where the idea of a fallback value comes in. What we want is that whenever a file with "Courier New" as the selected font is displayed by version 1.0, it will be displayed using "Tahoma".

This can not be done with the above enum. However, there is a solution, in the following form:

[Flags]
public enum Font
{
    Tahoma = 0x01,
    Arial  = 0x02,
    CourierNew = 0x05,
}

The idea is that since CourierNew also contains the bit for the Tahoma value, the first two statements will be true but the third won't:

Font courier = Font.CourierNew;
bool isCourierNew = ((courier & Font.CourierNew) == Font.CourierNew),
     isTahoma     = ((courier & Font.Tahoma)     == Font.Tahoma),
isArial = ((courier & Font.Arial) == Font.Arial);

If we wanted to add a new value in v1.2 for "Veredana" with a fallback to "Courier New", we will simply add a field with the value 0x0D (8 is the next unused bit or'd by 5, the value of "Courier New").

The only limitation to this is that you can only use as many bits as there are in the types enum can inherit.

Posted: Oct 10 2007, 12:15 PM by Omer van Kloeten | with 1 comment(s) |
Filed under:
Expression trees' ConstantExpression values

After reading Jafar Husain's posts (1, 2 and bonus by Doron Yaacoby), I started thinking about being able to strong type names using the Expression classes.

One of the things I came up with is creating a tracing framework where Expression is passed, instead of strings or other untyped methods.

[Conditional("DEBUG")]
public static void TraceStart<T, R>(
this T me, Expression<Func<T, R>> where) {
// ...
}

[Conditional("DEBUG")]
public static void TraceEnd<T, R>(
this T me, Expression<Func<T, R>> where, R returnValue) {
// ...
}

class Foo
{
public bool Bar(int param)
{
this.TraceStart(o => o.Bar(param));

this.TraceEnd(o => o.Bar(param), false);

return false;
}
}

Since the TraceStart and TraceEnd methods are decorated with a ConditionalAttribute, the Expression objects will not even be created (since the calls will not be made).

Nice idea, but the overhead during debugging might just be too much.

 

Here's where the interesting bit comes in: While I was fiddling with the idea, I tried to print the value of param, by reaching the expression tree's ConstantExpression for it. However, the type in the expression's Value property was of a type named: Namespace.Foo+<>c__DisplayClass0.

OK, so where do I get the value from? Apparently, Namespace.Foo+<>c__DisplayClass0 has a public field named value. That's where. Oh, but wait. You can't get it - since it's a field, you can't get it using polymorphism, but even if it was a property, Namespace.Foo+<>c__DisplayClass0 doesn't inherit or implement anything.

Resorting to reflection seems like a terrible solution. I just hope that this will change until C# 3.0 RTMs.

Posted: Oct 03 2007, 08:25 PM by Omer van Kloeten | with 4 comment(s)
Filed under: ,
More Posts