如何使用特定签名在C#中检查方法?

时间:2017-04-29 09:09:10

标签: c# overloading

我想检查某些参数的方法是否已实现。在这种情况下,我有例如这些方法重载:

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");}
}

假设我有小数:

object obj = 1M;

如果我现在致电TransformFrom(obj),我会收到例外情况。

我的程序的其他部分只返回对象,它们实际上是具体的类型,如int或datetime。我想将其中一些对象转换为字符串,以便将这些对象写入日志。所以这是一个运行时问题。另外,我希望我的Transformations-class足够通用,可以在其他程序中使用,因此可以有任何类型的对象。

是否有快速的方法可以发现此方法重载不存在?

2 个答案:

答案 0 :(得分:2)

无论哪种方式,您当前都会遇到编译时错误,即使存在接受小数的重载。您可以根据自己的需要采用以下两种方式之一:

要在编译时解决此问题,您必须转换为正确的类型。

object obj = 1;
var objAsInt = (int) obj;
var result = transformationInstance.TransformFrom(objAsInt);

如果没有正确的过载,您将收到编译时错误,您可以在设计时解决此问题。

要在运行时解决此问题,请使用反射来确定是否存在类型的重载以及是否传递了实例。

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});
}

答案 1 :(得分:0)

可以使用反射找出是否存在给定的重载:

public static bool HasOverloadForArgument(Type targetType, string methodName, object arg)
{
    var methodInfo = targetType.GetMethod(name: methodName, types: new[] { arg.GetType() });
    return methodInfo != null;
}

Live sample

我不确定这里的整个想法是什么,因为在运行期间转换不可用时,你可以做的事情不多。

也许,您最好使用dynamic来避免所有反射内容和其他需要的缓存,例如。

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