我有一些反射代码,我希望有一种方法可以将方法名称绑定到类型而不是通过字符串声明。
我有这个界面:
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#中的可能,请告诉我。
答案 0 :(得分:7)
从C#6开始,您将能够使用新的this语句来避免魔术字符串:
string methodName = nameof(IDoStuff<object>.Do);
编辑: @ 31eee384在评论中指出上述内容可以进一步简化如下:
nameof
关于新的nameof
声明,nameof有这个说法,这似乎与OP想要完成的内容非常一致:
您经常要捕获方法的字符串名称。使用
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)); } }
有助于在重命名定义时保持代码有效。之前必须使用字符串文字来引用定义,这在重命名代码元素时很脆弱,因为工具不知道检查这些字符串文字。
在C#6之前,它也可以通过使用表达式来避免魔术字符串,但它有点笨拙。这是一个适合您案例的例子。
首先,编写以下扩展方法:
IDoStuff<object> dummy = null; // don't need a valid instance.
string methodName = dummy.GetMethodName(t => t.Do(null)); // yay! still no magic strings.
然后你可以像这样使用它:
$.each(ids, function (i, value) {
var ids=["width_uncheck","thickness_uncheck"];
var names=['width','thickness'];
$("#"+ids[i] ).click(function() {
$('input:radio[name="'+names[i]+'"]').each(function(i) {
this.checked = false;
});
});
});
答案 1 :(得分:0)
创建通用方法DoIt
:
private void DoIt<T>(T stuff, IDoStuff<T> doer) {
doer.Do(stuff);
}
并称之为:
DoIt(GotThisFromSomewhereElse(), GotThisFromSomewhereElseAlso());
当然,GotThisFromSomewhereElseAlso
和GotThisFromSomewhereElse
也应该是泛型。