Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting to Generic base class failing

Tags:

c#

.net

generics

I am failing to see why my attempt to cast to a generic base class is not working.

The basic structure of the code is as follows.

interface ICmd
{
}

class Context
{
}

class Cmd<TContext> : ICmd
    where TContext : Context
{
}

class MyContext : Context
{
}

class MyCmd : Cmd<MyContext>
{
}

So now I have an instance of ICmd and want to cast it to Cmd as follows

var base = cmd as Cmd<Context>

base is always null after this line is executed.

changing cast to be specific for the context only and it works.

var base = cmd as Cmd<MyContext>       -- this works ???

Hope I have provided enough information, is this a covariance\contravariance issue?

Thanks

like image 907
RastaBaby Avatar asked May 12 '11 13:05

RastaBaby


People also ask

Can generic be void?

Currently, void is not allowed as a generic parameter for a type or a method, what makes it hard in some cases to implement a common logic for a method, that's why we have Task and Task<T> for instance. and use it as a generic parameter for any type or method.

Can generic class have non generic method?

Yes, you can define a generic method in a non-generic class in Java.

Can generic class be inherited?

Generic classes support an inheritance mechanism and can form hierarchies. Any generic class that takes a type T as a parameter can be inherited by another derived class. In this case, a parameter of type T is passed to the derived class.

What is generic class in asp net?

Generic is a class which allows the user to define classes and methods with the placeholder. Generics were added to version 2.0 of the C# language. The basic idea behind using Generic is to allow type (Integer, String, … etc and user-defined types) to be a parameter to methods, classes, and interfaces.


2 Answers

You may want to use co- and contravariance.

The problem is that Cmd<Context> is not the base class of Cmd<MyContext>.

See this recent question for a more detailed answer: C# Generics Inheritance Problem

like image 105
Daniel Hilgarth Avatar answered Nov 11 '22 05:11

Daniel Hilgarth


What you need here is covariance. C# 4 currently does not allow variance for generic type parameters in classes. If your interface doesn't need to allow using the TContext in any input positions, you can consider making the interface generic, and covariant in TContext:

interface ICmd<out TContext> where TContext : Context { }

class Cmd<TContext> : ICmd<TContext> where TContext : Context { }

static void Main(string[] args)
{
    Cmd<MyContext> cmd = new Cmd<MyContext>();

    var foo = cmd as ICmd<Context>;
}
like image 26
Yannick Motton Avatar answered Nov 11 '22 05:11

Yannick Motton