Nameof выражение в .net framework 4

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

nameof (ссылка на С# и Visual Basic)

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

Ответы

Ответ 1

Если вы говорите об эквиваленте для С# до С# 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'

Update:

Более всеобъемлющий (хотя все еще не такой красивый)

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

Ответ 2

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

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

Подробнее на MSDN

Ответ 3

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

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

    nameof(this.Property)
    
  • используйте метод, который принимает выражение, и возвращает имя свойства, найденное в этом сообщении Получить имя свойства, используя отражение

    var propertyName = GetPropertyName(  
        () => myObject.AProperty); // returns "AProperty"
    
  • 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;
    }
    

Ответ 4

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

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