Название выражения в.net Framework 4

Выражение "nameof" введено в Visual Studio 2015 и C# 6

nameof (C# и Visual Basic Reference)

Как вы можете использовать его или написать аналогичный метод в более старых версиях, таких как.net Framework 4.

4 ответа

Решение

Если вы говорите об эквиваленте C# до C#6, это позволит сделать работу (хакерским способом) для свойств. Вероятно, его можно расширить, включив в него поля, методы и т. Д.

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

nameOf - Получает разрешение в Compiletime - если вы декомпилируете, вы увидите, что компилятор просто перевел имя класса (без пространства имен (!)) в константную строку. Так что будьте в курсе!

Если вы хотите получить имя класса, используйте typeof() или же GetType() чтобы получить конкретный (возможно, производный) тип в Runtime и прочитайте значение
.Name-Собственность в.net

Узнайте больше на MSDN

Насколько мне известно, есть три варианта, чтобы не использовать магическую строку

  1. nameof, для которого требуется Visual Studio 2015 (но может быть скомпилировано с другими версиями.net framework)

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

Оператор nameof возвращает строковое представление переменной, которую вы передали, поэтому nameof(var1) вернет "var1", это полезно для избежания кода, в котором мы должны указывать имена переменных как строки, как в исключениях аргументов.

В предыдущих версиях вы могли добиться аналогичного эффекта, используя отражения или деревья выражений.

@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 уровня домена.

Другие вопросы по тегам