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?
source to share
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).
source to share