I'm trying to write generic method to cast types. I want write something like Cast.To<Type>(variable)
instead of (Type) variable
. My wrong version of this method:
public class Cast { public static T To<T>(object o) { return (T) o; } }
And this is simple test:
public class A { public static explicit operator B(A a) { return new B(); } } public class B { } A a = new A(); B b = Cast.To<B>(a);
As you guessed, this code will fail with InvalidCastException
.
Is this code fail because virtual machine doesn't know how to cast variable of type object
to type B
at run-time? But exception message says: "unable to cast object of type A to type B". So CLR knows about real type of variable o
, why it cannot perform casting?
And here is main question: how should I rewrite method T To<T>(object o)
to fix this problem?
In the general case, a generic type could be both a supplier and a consumer of its type parameters, which means that the type we get by casting the type parameter (up or down) cannot be either a subtype or a supertype of the original: they are unrelated types that cannot be cast between, which is exactly why the Java ...
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Advertisements. Generics allow you to define the specification of the data type of programming elements in a class or a method, until it is actually used in the program. In other words, generics allow you to write a class or method that can work with any data type.
All of what's been said about the operator resolution is correct...but this is my answer to your main question:
public static T To<T>(this object o) { return (T)(dynamic)o; }
The key here is that casting o to dynamic will force the .NET to search for the explicit operator at runtime.
Plus, why not make it an extension method?
Instead of
A a = new A(); B b = Cast.To<B>(a);
you can do
A a = new A(); B b = a.To<B>();
An added benefit of exposing it as an extension method is that you gain a fluent interface for explicit casting (if you like that sort of thing). I've always hated the amount of nested parenthesis balancing required for explicit casting in .NET.
So you can do:
a.To<B>().DoSomething().To<C>().DoSomethingElse()
instead of
((C)((B)a).DoSomething())).DoSomethingElse()
which, to me, looks clearer.
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