Reputation: 57
I want to check if the method for certain parameters is implemented. In this scenario, I have for example these method overloads:
public class Transformations
{
public string TransformFrom(string s) { return s;}
public string TransformFrom(int i) { return "00" + i.ToString();}
public string TransformFrom(DateTime dt) { return
DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff");}
}
Suppose I have decimal like:
object obj = 1M;
If I now call TransformFrom(obj)
, I get an exception.
Other part of my program returns unfortunately only objects, which really are concrete types like int or datetime. And I want to transform some of these objects to string so that those can be written to the log. So this is a runtime problem. Also I want that my Transformations-class is general enough to be used in other programs too, so there can be objects of any type.
Is there fast way to find out that this method overload does not exist?
Upvotes: 3
Views: 2557
Reputation: 2913
It is possible to find out whether a given overload exists using reflection:
public static bool HasOverloadForArgument(Type targetType, string methodName, object arg)
{
var methodInfo = targetType.GetMethod(name: methodName, types: new[] { arg.GetType() });
return methodInfo != null;
}
I'm not sure what is the whole idea here as there won't be much you can do when the transformation is not available during runtime.
Maybe, you'd just be best off using dynamic
to avoid all the reflection stuff and caching required otherwise, e.g.
var boxedInt = (object)1;
var boxedFloat = (object)1f;
dynamic dynamicInt = boxedInt;
dynamic dynamicFloat = boxedFloat;
var intResult = new Transformations().TransformFrom(dynamicInt); // works
var floatResult = new Transformations().TransformFrom(dynamicFloat); // throws binder exception
Upvotes: 1
Reputation: 62213
Either way you are currently going to get a compile time error, even if there was an overload that accepted a decimal. You can approach this one of 2 ways depending on your needs:
To resolve this at compile time you have to cast to the correct type.
object obj = 1;
var objAsInt = (int) obj;
var result = transformationInstance.TransformFrom(objAsInt);
If there is no proper overload you will get a compile time error and you can resolve this at design time.
To resolve this at runtime use reflection to figure out if there is an overload of the type and if there is pass the instance.
object obj = 1;
var underlyingType = obj.GetType();
var method = typeof(Transformations).GetMethod("TransformFrom", new Type[] { underlyingType });
if(method != null)
{
var result = method.Invoke(transformationInstance, new []{obj});
}
Upvotes: 3