在c#中是否有一种类型化的方式来声明方法名?
本文关键字:方式 类型化 声明 方法 一种 是否 | 更新日期: 2023-09-27 18:03:12
我有一些反射代码,我希望有一种方法将方法名绑定到类型,而不是通过字符串声明。
我有这样的接口:
interface IDoStuff<T> {
void Do(T stuff);
}
然后我有这个代码:
object stuff = GotThisFromSomewhereElse();
object doer = GotThisFromSomewhereElseAlso();
var doMethodInfo = doer.GetType().GetMethod("Do");
doMethodInfo.Invoke(doer, new[] { stuff });
问题是我不能简单地做一个安全强制转换并调用它,因为它是泛型的,而且我实际上不知道T是什么类型。
这工作得很好,但是当我重命名方法时,我必须去更新这个,我并不过分担心,因为我有测试来确认所有这些工作,这可以防止不知道它的变化。
它真的很丑,我很好奇是否有一些圆滑的方法可以让这个类型,这样如果我改变它,ReSharper就会重命名。
我真的很喜欢这样的东西:
object stuff = GotThisFromSomewhereElse();
object doer = GotThisFromSomewhereElseAlso();
var doMethodInfo = doer.GetType().Methods.Do;
doMethodInfo.Invoke(doer, new[] { stuff });
提前感谢,请告诉我这在c#中是否可能。
从c# 6开始,您将能够使用新的nameof语句来避免魔法字符串:
IDoStuff<object> dummy = null; // don't need a valid instance.
string methodName = nameof(dummy.Do) // yay! no magic strings.
EDIT: @31eee384在评论中指出,以上内容可以进一步简化如下:
string methodName = nameof(IDoStuff<object>.Do);
关于新的nameof
语句,文档有这样的说法,这似乎非常符合OP试图完成的任务:
通常需要捕获方法的字符串名称。在重命名定义时,使用
nameof
有助于保持代码的有效性。在此之前,您必须使用字符串字面量来引用定义,这在重命名代码元素时是很脆弱的,因为工具不知道检查这些字符串字面量。
在c# 6之前,也可以通过使用表达式来避免魔术字符串,但它有点笨拙。下面是一个适合你的例子。
首先,编写以下扩展方法:public static string GetMethodName<T>(this T instance, Expression<Action<T>> methodExpression)
{
if (methodExpression.Body is MethodCallExpression)
{
return ((MethodCallExpression)methodExpression.Body).Method.Name;
}
else
{
throw new ArgumentException(string.Format("Invalid method expression: {0}", methodExpression.Body));
}
}
然后你可以这样使用:
IDoStuff<object> dummy = null; // don't need a valid instance.
string methodName = dummy.GetMethodName(t => t.Do(null)); // yay! still no magic strings.
创建通用方法DoIt
:
private void DoIt<T>(T stuff, IDoStuff<T> doer) {
doer.Do(stuff);
}
并命名为:
DoIt(GotThisFromSomewhereElse(), GotThisFromSomewhereElseAlso());
当然,GotThisFromSomewhereElseAlso
和GotThisFromSomewhereElse
也应该是泛型