27

"nameof" 表达式在 Visual Studio 2015 和 c# 6 中引入

nameof(C# 和 Visual Basic 参考)

您如何在.net framework 4 等旧版本中使用它或编写类似的方法。

4

5 回答 5

30

如果您在谈论 C#6 之前的 C# 的等价物,这将完成属性的工作(以一种 hacky 方式)。它可能可以扩展到包括字段、方法等。

public static class TestExtension
{
    public static String nameof<T, TT>(this T obj, Expression<Func<T, TT>> propertyAccessor)
    {
        if (propertyAccessor.Body.NodeType == ExpressionType.MemberAccess)
        {
            var memberExpression = propertyAccessor.Body as MemberExpression;
            if (memberExpression == null)
                return null;
            return memberExpression.Member.Name;
        }
        return null;
    }
}

只是很快地把它搅了起来,所以还有很多需要改进的地方,但你可以像这样使用它:

public class myClass
{
    public string myProp { get; set; }
}

var a = new myClass();
var result = a.nameof(b => b.myProp);

结果包含“myProp”

更新:

更全面(虽然仍然不那么漂亮)

public static class TestExtension
{
    public static String nameof<T, TT>(this Expression<Func<T, TT>> accessor)
    {
        return nameof(accessor.Body);
    }

    public static String nameof<T>(this Expression<Func<T>> accessor)
    {
        return nameof(accessor.Body);
    }

    public static String nameof<T, TT>(this T obj, Expression<Func<T, TT>> propertyAccessor)
    {
        return nameof(propertyAccessor.Body);
    }

    private static String nameof(Expression expression)
    {
        if (expression.NodeType == ExpressionType.MemberAccess)
        {
            var memberExpression = expression as MemberExpression;
            if (memberExpression == null)
                return null;
            return memberExpression.Member.Name;
        }
        return null;
    }
}

访问静态属性/字段:

TestExtension.nameof(() => myClass.MyOtherField)

在函数中访问参数:

void func (int a) {
    TestExtension.nameof(() => a);
}
于 2015-07-07T07:22:07.567 回答
3

nameOf- 得到解决Compiletime- 如果你反编译,你会看到编译器只是将类名(没有命名空间(!))翻译成一个常量字符串。所以要注意!

如果您想获取类的名称,请使用typeof()GetType()获取特定的(可能是派生的)类型Runtime并读取.net < C#6中
的-Property 的值。.Name

在MSDN上阅读更多信息

于 2015-07-07T07:09:07.150 回答
3

据我所知,有三种选择不必使用魔术字符串

  1. nameof需要 Visual Studio 2015(但可以编译成其他版本的 .net 框架)

    nameof(this.Property)
    
  2. 使用接受表达式并返回属性名称的方法,如本文“使用反射获取属性的字符串名称”中所示

    var propertyName = GetPropertyName(  
        () => myObject.AProperty); // returns "AProperty"
    
  3. CallerMemberNameAttribute -(仅在 .net framework 4.5 中可用,包括在内,因为原始帖子说像 .net framework 4.0 这样的旧版本,我猜它包括 4.5)此方法的缺点是它仅在您需要当前方法的字符串表示时才有用你正在经营。

    public string IsChecked  {
       set{
           Console.WriteLine(GetCurrentMemberName()); // prints "IsChecked"
       }
    }
    
    string GetCurrentMemberName([CallerMemberName] string memberName = "")
    {
         return memberName;
    }
    
于 2015-07-08T03:59:38.707 回答
1

nameof 运算符返回您传递给它的变量的字符串表示形式,因此 nameof(var1) 将返回“var1”,它有助于避免我们必须将变量名称指定为字符串的代码,例如在参数异常中。

在以前的版本中,您可以使用反射或表达式树来实现类似的效果。

于 2015-07-07T07:11:03.800 回答
0

@Rob,非常感谢,但静态成员访问也可能适用于非静态类成员。

public static class TestExtension {
    public static String nameof<T>(this Expression<Func<T, object>> accessor)
    {
        return nameof(accessor.Body);
    }
}
class MyClass {
    public Guid MyOtherField;
}
TestExtension.nameof<MyClass>(o=>o.MyOtherField);

好消息是类不会被实例化。访问域层 DTO 很有用。

于 2020-03-27T19:26:51.040 回答