Abstract generic implicit conversion to derived type, error?

Suppose the following definition of abstract type A is:

public abstract class A<T, J> : where J : A<T, J>, new()
{
    public virtual T Value { get; set; }

    //Error: User-defined conversion must convert to or from the enclosing type
    public static implicit operator J(T value)
    {
        return new J
        {
            Value = value
        };
    }
}

      

The implicit operator causes the compiler to emit a "User-defined conversion must be converted to or from private type" error.

The implicit operator is converted to a derived enclosing type. Is this a bug or limitation of C #?

I am trying to generalize boxing type T to J.

Update:

Continuing with this error, I tried the following:

public abstract class A<T, J> : where J : Primary<T, J>, new()
{
    public virtual T Value { get; set; }

    public static implicit operator A<T, J>(T value)
    {
        return new J
        {
            Value = value
        };
    }

    public static implicit operator J(A<T, J> value)
    {
        return value as J;
    }
}

      

This prevents a compiler error (as expected), although it then forces an explicit conversion. Which is undesirable.

Essentially, I would like to be able to do the following:

public class B { }

public class C : A<B, C> 
{ 
    public C Foo(B b)
    {
        return b;
    }
}

      

Any other alternatives to the above to provide generic implicit type boxing?

+3


source to share


1 answer


The closest thing you can do to get your class A<T, J>

to work is:

public class A<T, J> where J : A<T, J>, new()
{
    public virtual T Value { get; set; }

    public static implicit operator A<T, J>(T value)
    {
        return new A<T, J>
        {
            Value = value
        };
    }
}

      

But once you check this one abstract

, it won't work because of new A<T, J>

. So it's nice here that you can rely on where J : A<T, J>, new()

to say that you are creating a derived type. But this is no longer valid C # syntax.

The bottom line is that you cannot do what you hope to do as an implicit conversion.

You can do an explicit conversion:



public abstract class A<T, J> where J : A<T, J>, new()
{
    public virtual T Value { get; set; }

    public static J Convert(T value)
    {
        return new J
        {
            Value = value
        };
    }
}

      

Now this will work:

public class B { }

public class C : A<B, C> 
{ 
    public C Foo(B b)
    {
        return C.Convert(b);
    }
}

      

There are very few network differences in the resulting code, but you have to do an explicit conversion (which is not bad for reading and maintaining the code).

+3


source







All Articles