c# - 有没有一种类型化的方法来在 C# 中声明方法名称

标签 c# .net reflection

我有一些反射代码,我希望有一种方法可以将方法名称绑定(bind)到类型,而不是通过字符串声明。

我有这个界面:

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.

编辑: @31eee384 在评论中指出,上面的内容可以进一步简化为:

string methodName = nameof(IDoStuff<object>.Do);

关于新的nameof声明,documentation有这样说,这似乎非常符合 OP 试图完成的目标:

you often want to capture the string name of a method. Using nameof helps keep your code valid when renaming definitions. Before you had to use string literals to refer to definitions, which is brittle when renaming code elements because tools do not know to check these string literals.


在 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.

关于c# - 有没有一种类型化的方法来在 C# 中声明方法名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31483437/

相关文章:

html - 为什么我的 bootstrap 响应表没有缩小

c# - 使用 LINQ 将对象集合转换为字典

java - 使用maven编译ParameterizedType时如何解决这个警告

scala - 如何检查 Scala HighKinded TypeTag 是否为数组?

c# - 使用运算符 <、<= 等测试两个对象

c# - 将递归替换为 TimerCallback 以迭代所有变体

c# - 字符串格式 % 带有效数字

c# - xamarin.mac 应用程序崩溃报告

c# - 如何在桌面应用程序中使用 DbContext 和 DI?

java - 这两种方法一起是一种递归形式吗?