我有一个看起来像MyClass.SpecialMethod()
的成员我需要将此方法的名称作为字符串发送到另一个方法。我知道我可以使用TypeOf.GetMethods(..).Name
但是...将被硬编码,如果SpecialMethod更改了名称,则会出现问题。
所以我想做的就是这样的事情
TypeOf(MyClass).GetMethod(MyClass.SpecialMethod).Name
这是可行的,如果是的话,怎么样?
我知道我可以从方法中获取当前方法的名称,但此时它已经很晚了。
答案 0 :(得分:3)
如果您可以使用nameof()
作为Jason suggested,请使用它。
如果不这样做,则编写此辅助方法:
class MyClass {
public void SpecialMethod() {
var myName = WhatIsMyName();
}
private static string WhatIsMyName([CallerMemberName] string name= "") {
return name;
}
}
有关详细信息,请参阅MSDN。请注意,如果调用者方法过载,您将获得其名称,但它不明确。
旧版 C#版本不支持它(它已在.NET 4.5中引入)。如果你必须处理它们,那么你可能需要采用堆栈行走的旧技巧来检查成员名称,大概是这样的:
[MethodImpl(MethodImplOptions.NoInlining)]
private static string WhatIsMyName() {
return new StackTrace().GetFrame(1).GetMethod().Name;
}
(请注意[MethodImpl(MethodImplOptions.NoInlining)]
以防止内联,否则如果内联此调用,您将跳过(GetFrame(1)
而非GetFrame(0)
)他们想要名称的方法。
请注意,所有这些技术(堆栈遍历,调用者信息,表达式)实际上都需要明确地调用另一个方法,其中nameof()
在编译时被解析时间即可。这可能是性能上的巨大差异(如果它是一个问题)。
答案 1 :(得分:2)
如果您选择C#6.0,则可以使用新的“nameof”关键字
nameof(MyClass.SpecialMethod)
在此查看更多信息(“表达名称”部分)
https://msdn.microsoft.com/en-us/magazine/dn802602.aspx
编辑:
文章中的用例示例:
namespace CSharp6.Tests
{
[TestClass]
public class NameofTests
{
[TestMethod]
public void Nameof_ExtractsName()
{
Assert.AreEqual<string>("NameofTests", nameof(NameofTests));
Assert.AreEqual<string>("TestMethodAttribute",
nameof(TestMethodAttribute));
Assert.AreEqual<string>("TestMethodAttribute",
nameof(
Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute));
Assert.AreEqual<string>("Nameof_ExtractsName",
string.Format("{0}", nameof(Nameof_ExtractsName)));
Assert.AreEqual<string>("Nameof_ExtractsName",
string.Format("{0}", nameof(
CSharp6.Tests.NameofTests.Nameof_ExtractsName)));
}
}
}
答案 2 :(得分:2)
有<config>
<frontend>
<layout>
<updates>
<contactredirect>
<file>contactredirect.xml</file>
</contactredirect>
</updates>
</layout>
</frontend>
</config>
方式:
<layout version="0.1.0">
<contacts_index_index translate="label">
<reference name="contacts.form">
<action method="setTemplate">
<template>contactredirect/form.phtml</template>
</action>
</reference>
</contacts_index_index>
</layout>
请注意,慢 ...
使用它像:
Expression
或者,如果方法有一些参数,请放置一些正确类型的值。该方法未执行,因此不是问题:
public static string GetName<TResult>(Expression<Func<TResult>> exp)
{
return GetName(exp != null ? exp.Body as MethodCallExpression : null);
}
public static string GetName(Expression<Action> exp)
{
return GetName(exp != null ? exp.Body as MethodCallExpression : null);
}
private static string GetName(MethodCallExpression mce)
{
if (mce == null)
{
throw new ArgumentNullException();
}
return mce.Method.Name;
}
答案 3 :(得分:2)
C#6 nameof 非常整洁。
目前,您可以在.NET 4.5中使用 CallerMemberName 属性,但如果您无法使用该属性,或者该名称不是来自调用者,则可以从Expression中提取名称。 Someone已经为此做了一个实用工具。以下是他的代码。它生成代码refactoring-friendly。
工作原理:
//Should return "Length", value type property
StaticReflection.GetMemberName<string>(x => x.Length);
//Should return "Data", reference type property
StaticReflection.GetMemberName<Exception>(x => x.Data);
//Should return "Clone", method returning reference type
StaticReflection.GetMemberName<string>(x => x.Clone());
//Should return "GetHashCode", method returning value type
StaticReflection.GetMemberName<string>(x => x.GetHashCode());
//Should return "Reverse", void method
StaticReflection.GetMemberName<List<string>>(x => x.Reverse());
//Should return "LastIndexOf", method with parameter
StaticReflection.GetMemberName<string>(x => x.LastIndexOf(','));
他的完整代码:
public static class StaticReflection
{
public static string GetMemberName<T>(
this T instance,
Expression<Func<T, object>> expression)
{
return GetMemberName(expression);
}
public static string GetMemberName<T>(
Expression<Func<T, object>> expression)
{
if (expression == null)
{
throw new ArgumentException(
"The expression cannot be null.");
}
return GetMemberName(expression.Body);
}
public static string GetMemberName<T>(
this T instance,
Expression<Action<T>> expression)
{
return GetMemberName(expression);
}
public static string GetMemberName<T>(
Expression<Action<T>> expression)
{
if (expression == null)
{
throw new ArgumentException(
"The expression cannot be null.");
}
return GetMemberName(expression.Body);
}
private static string GetMemberName(
Expression expression)
{
if (expression == null)
{
throw new ArgumentException(
"The expression cannot be null.");
}
if (expression is MemberExpression)
{
// Reference type property or field
var memberExpression =
(MemberExpression) expression;
return memberExpression.Member.Name;
}
if (expression is MethodCallExpression)
{
// Reference type method
var methodCallExpression =
(MethodCallExpression) expression;
return methodCallExpression.Method.Name;
}
if (expression is UnaryExpression)
{
// Property, field of method returning value type
var unaryExpression = (UnaryExpression) expression;
return GetMemberName(unaryExpression);
}
throw new ArgumentException("Invalid expression");
}
private static string GetMemberName(
UnaryExpression unaryExpression)
{
if (unaryExpression.Operand is MethodCallExpression)
{
var methodExpression =
(MethodCallExpression) unaryExpression.Operand;
return methodExpression.Method.Name;
}
return ((MemberExpression) unaryExpression.Operand)
.Member.Name;
}
}
答案 4 :(得分:0)
请尝试使用c#的 请参阅网址:https://msdn.microsoft.com/en-us/library/hh534540.aspx