Given these types:
class A { }
class B
{
public static implicit operator A(B me)
{
return new A();
}
}
class Test<T> where T : A { }
I tried
var b = new Test<B>();
And expected it to fail, which it did. But the error message is
The type 'B' cannot be used as type parameter 'T' in the generic type or method 'Test'. There is no implicit reference conversion from 'B' to 'A'.
But there is an implicit reference conversion from B to A. Is this just a strange message? There is not an implicit reference conversion as Adam Robinson's answer shows. The message is correct.
Note that MSDN says:
where T : (base class name) - The type argument must be or derive from the specified base class.
Which explains why it is not allowed since B
does not derive from A
You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.
A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)
By using where keyword, we can apply constraints on generics. In c#, you can apply multiple constraints on generic classes or methods based on your requirements. In c#, you have a different type of constraints available; those are class, structure, unmanaged, new(), etc.
No, what you're trying to do is not possible. An implicit reference conversion is not the same thing as an implicit type conversion. Your code defines an implicit type conversion, which is where you could do the following:
B foo = new B();
A bar = foo;
Note, however, that foo
and bar
now contain different references. The implicit type conversion creates a new instance of A
that should be (by convention) logically equivalent to foo
. But the point is that it's a different reference.
A reference conversion would be where the reference itself does not change, which means that the type in question must either inherit from (for classes) or implement (for interfaces) the type in question. If I do this:
class A { }
class B : A { }
Then my code above will now hold the same reference in foo
and bar
. This is what is meant by an implicit reference conversion. Conversely, an explicit reference conversion would be downcasting, like this:
A foo = new B();
B bar = (B)foo;
Again, the references are the same, but the cast was explicit.
So, in short, the MSDN documentation is clearer but less precise.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With