views:

71

answers:

2

Suppose you have an interface like this:

public interface IDoSomething<out T>
{
    T DoSomething(object value);
}

To be able to call DoSomething on that interface without knowing the type of T, you have to create this:

public interface IDoSomething
{
    object DoSomething(object value);
}

Modify your original interface to inherit from the new one:

public interface IDoSomething<out T> : IDoSomething
{
    new T DoSomething(object value);
}

And then do this:

((IDoSomething)obj).DoSomething();

'''But''' then you have to implement the DoSomething method on your implementation twice; once explicitly and once implicitly.

One solution that partly works is to do this:

((IDoSomething<object>)obj).DoSomething();

But this only works if the generic type is a reference type; value types like DateTime and int won't work, even though they too inherit from object. Why is this?!

Is there a solution to this conundrum yet (without employing abstract classes!)?

+3  A: 

Well value types are not supported.

Implication and the reason behind, as far as I know, mainly involves the difference in storage of arrays.

Let's imagine we have:

Byte[] bb = new Byte[20];
byte b = 255;
bb[0] = b; // here value is copied into the array
b = 128;
Console.WriteLine(bb[0]); // will print 255

So changing the b does not change the value we have assigned and this is expected. But what if we do something like this:

object[] bb = new Byte[20]; // throws exception

System treats object arrays differently and stores the pointer and not the value. We actually have only one type of object array (from the structure point of view not type) and that is pointer array while arrays for value types store the value.

Aliostad
+1, but the last paragraph sounds a bit weird: "We actually have only one type of object array": Of course there are different array *types* in the .NET type system. They just have the same representation in memory, so casting between arrays is possible without moving or copying the data. The same is not generally true for arrays of value types. I guess that's what you meant.
nikie
What it means, internally CLR keeps an array of pointers for object arrays. So if it is ObjectA[] or ObjectB[], from the structure point of view it does not matter although the type knows what kind of array it is.
Aliostad
+3  A: 

This article explains why variance doesn't work for value types (about 1/4 the way down). Basically, int -> object changes the representation of the data (it requires boxing), where as string -> object simply changes the pointer type.

thecoop