[英]Invoke “ToString” method by reflection
我正在尝试按如下方式检索 MethodInfo“ToString”:
MethodInfo method = MyType.GetMethod("ToString",
BindingFlags.Public | BindingFlags.Instance);
抛出异常“找到歧义匹配”。
您的类型包含多个ToString()
重载,而GetMethod
不知道您想要哪一个。
使用以下语法指定您想要不带任何参数的重载:
MethodInfo method = myType.GetMethod("ToString", Type.EmptyTypes);
注意:由于ToString()
是在System.Object
上定义的,你不需要反射来在未知类型的对象上调用它:
object myObject = ...;
string s = myObject.ToString(); // works
ToString()
是System.Object
的成员,因此它是极少数不需要反射的方法之一,当您在未知类型上调用它时。
例外情况是 Tostring 的重载(即int.ToString(string format)
但要调用其中之一,您必须知道您要查找的是哪一个。
而这些重叠会导致您看到的错误。 你必须是具体的。
可能有不止一种ToString()
方法。 例如double
有四个变体( virtual object.ToString()
的覆盖加上三个变体)
尝试
var variants = MyType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.Name == "ToString");
它将返回ToString
所有变体
或者,如果您知道“您的” ToString
的参数
var toString = MyType.GetMethod("ToString",
BindingFlags.Public | BindingFlags.Instance,
null, arrayOfParametersType, null);
您需要指定您想要没有参数的那个:
var method = MyType.GetMethod("ToString",
new Type[0]);
BindingFlags.Public | BindingFlags.Instance
BindingFlags.Public | BindingFlags.Instance
为默认值,无需指定。
MethodInfo method = typeof(MyType).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance);
这实际上对我有用...
您可能在 ToString 上有一个重载。 由于您可以拥有多个公开的 ToString 方法(重载),因此该行可以返回多个 ToString 方法。
你必须使用类似的东西:
GetMethod(字符串名称,类型 [] 类型)
其中 Type[] 包含您正在搜索的方法的类型数组(在您的情况下没有)
(感谢评论,也从中学到了一些东西:)
ToString
可以重载。 在许多类型上都是如此。
首先,您应该检查您要调用的ToString
是被覆盖的IFormattable.ToString(string format, IFormatProvider formatProvider))
object.ToString()
还是IFormattable.ToString(string format, IFormatProvider formatProvider))
,因为在这些情况下您可以简单地避免反射。
您可以使用采用Type[] types
参数的GetMethod
重载来选择所需的ToString
重载。
例如,您可以使用GetMethod("ToString",new Type[]{})
来获取无参数的ToString()
。
检查是否要覆盖ToString()
是否真的使用了override
关键字:
class MyType
{
public override string ToString()
{
return "Whatever";
}
}
否则,您将隐藏 object.ToString() 版本而不是真正覆盖。
在这样的场景中,当您知道该方法存在时(可能有许多重载使问题复杂化),使用为您完成繁重工作的反射帮助程序库会很有帮助。
例如,Fasterflect 允许您简单地执行以下操作,以便使用给定提供的参数的“最佳可用匹配”调用方法(在下面的示例中,可选参数 42 表示您在调用方法时要使用的某个值):
var obj = ...
var result = obj.TryCallMethodWithValues( "ToString", 42 );
根据我的经验,使用经过良好测试的库而不是手动编码(在本例中为反射)会很快得到回报。
免责声明:我是 Fasterflect 项目的贡献者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.