I've some issues with the following piece of code. I would like to explicit a string to an object, this is working perfectly fine, however, if this object is part of a generic class, this is failing with the following error exception: "Unable to cast object of type 'System.String' to type 'test.B'". Even though I've overloaded the the method.
using System;
using System.Collections.Generic;
namespace test {
class Program {
static void Main(string [] args) {
// These two cast perfectly fine.
B x = (B) "abc";
C y = (C) "def";
A <B> a = new A<B>();
a.b();
A <C> b = new A<C>();
b.b();
}
}
class A<T> {
public List <T> a = new List<T>();
public void b() {
// Unable to cast object of type 'System.String' to type 'test.B'
this.a.Add ((T) (object) "abc");
this.a.Add ((T) (object) "def");
this.a.Add ((T) (object) "ghi");
}
}
class B {
public string b;
public static explicit operator B(string a) {
B x = new B();
x.b = a;
return x;
}
}
class C {
public string c;
public static explicit operator C(string a) {
C x = new C();
x.c = a;
return x;
}
}
}
It would be awesome if somone could explain to me why this isn't casting properly.
Thanks
Conversion operators only apply when the type is known statically; after all, generic methods need to use the exact same IL for every T
- so it can't call your operator in some cases, and a type-check in others.
Additionally, because you've explicitly cast to object
, it will never be used; a cast from object
is always a simple unbox or type check.
An evil fix would be (and I don't like this):
this.a.Add((T)(dynamic)"abc");
this.a.Add((T)(dynamic)"def");
this.a.Add((T)(dynamic)"ghi");
which defers the resolution to runtime. It works, but I would need to wash my eyes after that. More generally, though: operators and generics do not play nicely - so: try not to use that combination in your API. I really wouldn't use the above, personally!
Compiler has no knowledge at compile time if generic parameter has explicit cast you are using.
You can introduce interface though, and put constrain on generic parameter
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