tags:

views:

67

answers:

2

Hello,

I have following code

public interface IEntity
{
    int Id { get; set; }
}

public interface ICriteria<T> where T : class,IEntity
{
    T GetResult(int id);
}

public class DummEntity : IEntity
{
    public int Id { get; set; }
}

public class SimpleCriteria<T>:ICriteria<T> where T:class,IEntity
{
    public T GetResult(int id)
    {
        return default(T); 
    }
}

should this type casting work ?

SimpleCriteria<DummEntity> scr = new SimpleCriteria<DummEntity>();
ICriteria<IEntity> generic = (ICriteria<IEntity>)scr;
+1  A: 

No, I don't think it will. scr is of type SimpleCriterial<DummyEntity> yet you're trying to cast it to ICriteria<IEntity> which it is not. Yes, DummyEntity is an IEntity, but that's where covariance bites you in the ass.

BFree
+7  A: 

Not in C# 3, no. Although the CLR has supported generic variance for interfaces and delegates since .NET 2.0, it hasn't been exposed in C# until version 4.

In C# 4 it will work - but only after you've made ICriteria<T> covariant:

public interface ICriteria<out T> where T : class,IEntity
{
    T GetResult(int id);
}

Note that in C# 3 the explicit cast means that it will compile - but it will fail at execution time.

Using C# 4 and the above declaration of ICriteria<T>, the conversion is implicit:

SimpleCriteria<DummEntity> scr = new SimpleCriteria<DummEntity>();
ICriteria<IEntity> generic = scr;
Jon Skeet
thanks Jon, is it that the language doesnt implement this feature, or is that my concept of covariance not clear ?
@ashish: Until C# 4, C# has not supported generic variance.
Jon Skeet