.net framework 4 中的 nameof 表达式

nameof expression in .net framework 4

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

中引入

nameof (C# and Visual Basic Reference)

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

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

如果你想得到一个类的名字,使用typeof()GetType()Runtime处得到特定的(可能派生的)类型并读取
的值 .net < C#6.

中的 .Name-属性

MSDN

阅读更多内容

nameof 运算符 return 是您传递给它的变量的字符串表示形式,因此 nameof(var1) 将 return "var1",它有助于避免我们必须指定的代码变量名称作为字符串,就像在参数异常中一样。

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

如果您谈论的是 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;
    }
}

访问静态properties/fields:

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

在函数内访问参数:

void func (int a) {
    TestExtension.nameof(() => a);
}

据我所知,有三个选项可以不必使用魔术字符串

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

    nameof(this.Property)
    
  2. 使用一种方法,该方法采用表达式和 returns 属性 名称,如在此 post“Get string name of property using reflection

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

    public string IsChecked  {
       set{
           Console.WriteLine(GetCurrentMemberName()); // prints "IsChecked"
       }
    }
    
    string GetCurrentMemberName([CallerMemberName] string memberName = "")
    {
         return memberName;
    }
    

@Rob,非常感谢,但是静态成员访问也可以用于非静态 class 成员。

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);

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