Dan Newcome, blog

I'm bringing cyber back

Why aren’t there generic properties in C#?

with 3 comments

I ran across something interesting today about the C# generics language feature and its underlying CLR support.

While maintaining a library of helper functions I thought it would be nice to be able to index into a collection of mixed-type properties and cast the result using a type specified by a generic type parameter. The calling code would have looked something like this:

// not valid code
string val = collection<string>[ "key" ];

Seems simple enough, we can have generic fields in our classes, and generic methods, so it seems like generic properties and indexers would follow.

However, the difference is that a property is a wrapper around a backing store. With a generic type field, we cannot provide a type argument at any time other than the class instantiation obviously, since setting a field is a simple assignment.

The crucial difference is when the type is known. In the case of a generic field we know the type when the class is instantiated with the type argument.

For example:

public class Gen<T> {
    public T Field;
}

Gen<string> gen = new Gen<string>();
gen.Field = "foo";

So why can’t we have:

public class Gen {
    public T Field<T> { get; set; };
}

Gen gen = new Gen();
gen.Field<string> = "foo";

As I alluded to before, the reason has to do with the underlying implementation of the heap in the CLR. Since we don’t know the type when the class is instantiated, the CLR can’t allocate it properly on the heap since it doesn’t know how much space it needs.

The only explanation that I found is an old post by a member of the C# team here.

Thinking about this some more I think it should be possible technically if the type were constrained to reference types.

Using generic type parameter constraints we would write:

public class Gen {
    public T Field<T> where T : class  { get; set; };
}

As long as we are storing a reference type it shouldn’t matter what it is since the pointer is the same size.

Also, if we abused the getter/setter a bit and used a collection as the backing store, it seems like everything should work, but the compiler enforces the constraints based on the common use case of properties, which is to wrap private fields to fire events and do logging perhaps, not to substitute for methods that manage back end storage.

This is pure speculation, but it is an interesting thought exercise.

Advertisements

Written by newcome

February 18, 2011 at 7:56 pm

Posted in Uncategorized

3 Responses

Subscribe to comments with RSS.

  1. It’s not of the exact same reason, but it’s related, and it’s a rather large PITA imho: You can’t use generics in Attributes either, since their type has to be known at compile time. However, there are neat things you can do with generics that doesn’t require open types, such that the type information could be known compile-time. The stuff I’m thinking about is:

    [PropertyReference(x => x.SomeProperty)]

    Here, the type “x” represents could be known at compile time (since PropertyReference can have it hard coded), but just because it uses generics, it’s not allowed in an Attribute, which I think sucks. I hope they open up for these kinds of things in the future.

    asbjornu

    June 24, 2011 at 12:38 am

  2. That’s a good observation. I hadn’t tried to use generic Attributes so I didn’t realize C# didn’t support them. Apparently the CLR doesn’t have any limitations in that regard, it appears only to be a restriction in C#. I found Jon Skeet’s explanation of this on this Stack Overflow question. http://stackoverflow.com/questions/294216/why-does-c-forbid-generic-attribute-types

    newcome

    June 24, 2011 at 8:15 am

  3. Yea, I’ve read that Stack Overflow before. I find it strange that the C# team considers this “a use case that doesn’t add much value”. Being able to rid the language of magic strings adds a lot of value imho.

    asbjornu

    June 25, 2011 at 4:52 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: