Search code examples
c#genericscastingpolymorphismdowncast

Interface downcasting with generics


I have the following code where I want to downcast to an interface with generic but I get Run-time exception: Unable to cast object of type 'FinalAssociator' to type 'IAssociator`1[Common]'.

public interface ICommon 
{
    string Name {get;set;}
}
public class Common : ICommon 
{
    public string Name {get;set;}
}
public class FinalCommon : Common {}
public interface IAssociator<T> where T : ICommon
{
    void HandleEvent(T data);
}
public abstract class Associator<T> : IAssociator<T> where T : ICommon
{
    public abstract void HandleAnotherEvent(T data);
    public void HandleEvent(T data)
    {
        HandleAnotherEvent(data);
    }
}
public class FinalAssociator : Associator<FinalCommon>
{
    public override void HandleAnotherEvent(FinalCommon data)
    {
        Console.WriteLine(data.Name);
    }
}
var x = new FinalAssociator();
var y = new FinalCommon { Name = "John" };
var z = (IAssociator<Common>)x;
z.HandleEvent(y);

Solution

  • You can't do this because it could lead to runtime errors due to invalid types, which is one of the things generics is intended to prevent. Consider what would happen if the compiler allowed your code. You have:

    z.HandleEvent(y);
    

    Here y is an instance of FinalCommon, which won't present a problem. However, what if you instead passed in something else, like:

    z.HandleEvent(new Common());
    

    This would result in your passing an instance of something that isn't FinalCommon to your method that is definitely expecting an instance of FinalCommon. This would be illegal, and the compiler prevents you from getting into this situation.