Breaking the Rules of C#
September 14, 2006 on 12:58 pm | In .NET Coding |Dynamic Casting at Runtime
Now you might think that c# is a strongly typed language, but I’ve just discovered a way that you can squeeze yourself through the door of reasonable doubt, if you happen to be in court trying to prove to the contrary.
Now, no fair emitting IL to emulate VB’s cast, and no fair using Type Conversion (which is more costly in the cases when you actually want to do this). The Dynamic Casting helps if you’re working around the fact that Delegates are NOT covariant with respect to Parameters. (They are with return values).
So, in this case, we just want to spoof the ’signature’ of the delegate out by accepting object, when we actually want to cast it to what it really is in the underlying value. It’s still a typesafe operation, it just kinda pulls the wool over the compiler’s eyes.
Lets say we have a delegate
public delegate object InvokeOp(object value);
Let’s also say that we’re screwed and have to call a method that only accepts stronly typed values.
public static FooClass
{
public static string Op(string value);
public static int Op(int value);
public static DateTime Op(DateTime value);
}
We’ll say that we want to write a single function that will call the appropriate one of these things at runtime, but we don’t want all this if logic all over the place.
public static class MyInvokerClass
{
static Dictionary<Type, InvokeOp> Invokers = new Dictionary<Type,InvokeOp>();
static MyInvokerClass()
{
//The trick way
Invokers.Add(typeof(string), delegate(object value) { FooClass.Op((string)value); });
Invokers.Add(typeof(int), delegate(object value) { FooClass.Op((int)value); });
Invokers.Add(typeof(DateTime), delegate(object value) { FooClass.Op((DateTime)value); });
}
// matches the signature of the delegate
public static object InvokeMethodFor(object value)
{
return Invokers[value.GetType()](value);
}
}
There! That wasn’t so bad was it?
That works well for calling methods that need specific types, and anonymous methods seem to let us break the rule (though actually just work around it) of contravariance -> we’re simulating Covariance.
Now that works just fine if you know all the types you want to use at runtime. But, you might say, is there a way that we can get this thing to work generically for all types on any method set like this?
Yes, there is, but I don’t have time to go into it right now. I’ll post back soon.
No Comments yet »
RSS feed for comments on this post. TrackBack URI
Leave a comment
Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds.
Valid XHTML and CSS. ^Top^
