2

I'm trying to do this:

interface IA
{
}

class A : IA
{
}

class Foo<T> where T: IA
{
}

class Program
{
    static void Main( string[] args )
    {
        Foo<A> fooA = new Foo<A>();
        Foo<IA> fooIA = fooA as Foo<IA>;
    }
}

However, the cast from Foo<A> to Foo<IA> does not compile. I recall seeing covariance issues like this when casting between List<T>'s, but I didn't think it applied to simple generics like this.

What is a good work around to getting this cast to work? How do I solve this problem?

void.pointer
  • 24,859
  • 31
  • 132
  • 243

4 Answers4

3

All generic classes are invariant. Interfaces (and delegates) on the other hand can support co- and contra-variance, but only in the cases where it's possible safely. And they need to opt-in explicitly.

For example via IFoo<out T> or IFoo<in T>

Servy
  • 202,030
  • 26
  • 332
  • 449
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1
interface IA
    {
    }

    class A : IA
    {
    }

    interface IFoo<T> where T : IA
    {
    }

    class Foo<T> : IFoo<T> where T : IA
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            IFoo<A> fooA = new Foo<A>();
            Foo<IA> fooIa = fooA as Foo<IA>;
        }
    }
Boris Modylevsky
  • 3,029
  • 1
  • 26
  • 42
1

those classes perform operations on those base types and NEVER need to downcast them

Then why do you need a Foo<A> to begin with? Declare it as Foo<IA> and add A's to it.

Joel C
  • 5,547
  • 1
  • 21
  • 31
0

Sorry this is in java but you could do something like this:

interface Alpha
{
}

class Beta implements Alpha
{
}  

class Foo<T>
{
}

class Program
{
    static void main(string[] args)
    {
        Foo<Beta> fooBeta = new Foo<Beta>();
        Foo<? implements Alpha> fooAlpha = fooBeta;
    }
}

This doesn't solve the issue completely but you get you can at least get access to all of the Alpha methods without knowing about Beta...

Dylan Watson
  • 2,283
  • 2
  • 20
  • 38