Skip to main content
added 1 character in body
Source Link
D. A.
  • 33
  • 7

I have written the following piece of code in an attempt to provide a type-safe interface:

namespace MWE
{
    public abstract class C {}
    public class A : C {}
    public class B : C {}

    public class Container<T> where T : C
    {
        public readonly T Value;

        public static implicit operator T(Container<C> c)
        {
            return c.Value;
        }
    }

    public interface IWrapper<out TC> where TC : C {}

    public class Foo
    {
        public Foo(IWrapper<Container<C>> wrapper) {}
    }
}

Unfortunately this doesn't compile. The Compiler<C>Container<C>-part of the wrapper parameter to the Foo constructor causes the compiler to produce the following error:

The type 'MFE.Container<MFE.C>' cannot be used as type parameter 'TC' in the generic type or method 'IWrapper<TC>'. There is no implicit reference conversion from 'MFE.Container<MFE.C>' to 'MFE.C'.
The type 'MFE.Container<MFE.C>' must be convertible to 'WeirdTestStuff.C' in order to use it as parameter 'TC' in the generic interface 'MFE.IWrapper<out TC>'.

I can't figure out where the problem is exactly, since the Covariance for the conversion seems to be there and there is even an implicit conversion from a Container<T> to T defined. Since T : C, I assumed it should just work like this.

I'd like to keep Foo's constructor as is if possible.

I hope someone can point me to a solution of this problem

I have written the following piece of code in an attempt to provide a type-safe interface:

namespace MWE
{
    public abstract class C {}
    public class A : C {}
    public class B : C {}

    public class Container<T> where T : C
    {
        public readonly T Value;

        public static implicit operator T(Container<C> c)
        {
            return c.Value;
        }
    }

    public interface IWrapper<out TC> where TC : C {}

    public class Foo
    {
        public Foo(IWrapper<Container<C>> wrapper) {}
    }
}

Unfortunately this doesn't compile. The Compiler<C>-part of the wrapper parameter to the Foo constructor causes the compiler to produce the following error:

The type 'MFE.Container<MFE.C>' cannot be used as type parameter 'TC' in the generic type or method 'IWrapper<TC>'. There is no implicit reference conversion from 'MFE.Container<MFE.C>' to 'MFE.C'.
The type 'MFE.Container<MFE.C>' must be convertible to 'WeirdTestStuff.C' in order to use it as parameter 'TC' in the generic interface 'MFE.IWrapper<out TC>'.

I can't figure out where the problem is exactly, since the Covariance for the conversion seems to be there and there is even an implicit conversion from a Container<T> to T defined. Since T : C, I assumed it should just work like this.

I'd like to keep Foo's constructor as is if possible.

I hope someone can point me to a solution of this problem

I have written the following piece of code in an attempt to provide a type-safe interface:

namespace MWE
{
    public abstract class C {}
    public class A : C {}
    public class B : C {}

    public class Container<T> where T : C
    {
        public readonly T Value;

        public static implicit operator T(Container<C> c)
        {
            return c.Value;
        }
    }

    public interface IWrapper<out TC> where TC : C {}

    public class Foo
    {
        public Foo(IWrapper<Container<C>> wrapper) {}
    }
}

Unfortunately this doesn't compile. The Container<C>-part of the wrapper parameter to the Foo constructor causes the compiler to produce the following error:

The type 'MFE.Container<MFE.C>' cannot be used as type parameter 'TC' in the generic type or method 'IWrapper<TC>'. There is no implicit reference conversion from 'MFE.Container<MFE.C>' to 'MFE.C'.
The type 'MFE.Container<MFE.C>' must be convertible to 'WeirdTestStuff.C' in order to use it as parameter 'TC' in the generic interface 'MFE.IWrapper<out TC>'.

I can't figure out where the problem is exactly, since the Covariance for the conversion seems to be there and there is even an implicit conversion from a Container<T> to T defined. Since T : C, I assumed it should just work like this.

I'd like to keep Foo's constructor as is if possible.

I hope someone can point me to a solution of this problem

Source Link
D. A.
  • 33
  • 7

"no implicit reference conversion" even though conversion is defined

I have written the following piece of code in an attempt to provide a type-safe interface:

namespace MWE
{
    public abstract class C {}
    public class A : C {}
    public class B : C {}

    public class Container<T> where T : C
    {
        public readonly T Value;

        public static implicit operator T(Container<C> c)
        {
            return c.Value;
        }
    }

    public interface IWrapper<out TC> where TC : C {}

    public class Foo
    {
        public Foo(IWrapper<Container<C>> wrapper) {}
    }
}

Unfortunately this doesn't compile. The Compiler<C>-part of the wrapper parameter to the Foo constructor causes the compiler to produce the following error:

The type 'MFE.Container<MFE.C>' cannot be used as type parameter 'TC' in the generic type or method 'IWrapper<TC>'. There is no implicit reference conversion from 'MFE.Container<MFE.C>' to 'MFE.C'.
The type 'MFE.Container<MFE.C>' must be convertible to 'WeirdTestStuff.C' in order to use it as parameter 'TC' in the generic interface 'MFE.IWrapper<out TC>'.

I can't figure out where the problem is exactly, since the Covariance for the conversion seems to be there and there is even an implicit conversion from a Container<T> to T defined. Since T : C, I assumed it should just work like this.

I'd like to keep Foo's constructor as is if possible.

I hope someone can point me to a solution of this problem