Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to properly type nested classes with generics in C#

I’m trying to get the C# equivalent of this Kotlin code:

class Baz<E>(val value: E)

class Foo<T>(val toto: Baz<T>) {

    class Bar<U>(toto: Baz<U>) : Foo<U>(toto) {

        val tata: U = toto.value

    }

}

This works because the U in Bar is the same as the T in Foo, so the same as E in Baz.

Keep in mind that Bar is a nested class, not an inner class, so Bar couldn’t have a type for toto if it didn’t have the generic U.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I then tried to replicate it in C# like this:

public class Baz<E> {
    public E Value;

    public Baz(E value) {
        Value = value;
    }
}

public class Foo<T> {
    public T Toto;

    public Foo(T toto) {
        Toto = toto;
    }

    public class Bar<U> : Foo<U> {
        public U Tata;

        public Bar(U toto) : base(toto) {
            Tata = toto.Value;
        }
    }
}

However, with this implementation, I get the error Cannot convert source type 'U' to target type 'T'.

Why doesn’t it work and how can I fix it?

>Solution :

However, with this implementation, I get the error Cannot convert source type ‘U’ to target type ‘T’.

Just remove U, because Bar<U> is already generic over T in Foo<T>:

This compiles for me:

public class Foo<T>
{
    public readonly T Toto;

    public Foo( T toto )
    {
        this.Toto = toto;
    }

    public class Bar : Foo<T>
    {
        public readonly T Tata;

        public Bar( T toto )
            : base( toto )
        {
            this.Tata = toto;
        }
    }
}

If you want to allow Bar to have its own type-parameter that’s bound to T that’s also doable (but of questionable utility, imo):

public class Foo<T>
{
    public readonly T Toto;

    public Foo( T toto )
    {
        this.Toto = toto;
    }

    public class Bar<U> : Foo<T>
        where U : T
    {
        public readonly U Tata;

        public Bar( U toto )
            : base( toto )
        {
            this.Tata = toto;
        }
    }
}

Note that in order to use Bar<U> you need to qualify it as Foo<T>.Bar<U>:

Foo<T> foo = new Foo<T>.Bar<U>( ... );

…so when T == U you end-up with this:

Foo<String> foo = new Foo<String>.Bar<String>( "lolwut" );
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading