Как получить имя текущего свойства

у меня есть класс

public class News : Record
{
    public News()
    {
    }

    public LocaleValues Name { get; set; }
    public LocaleValues Body;
}

И в моем классе LocaleValues у меня есть:

public class LocaleValues : List<LocalizedText>
{
    public string Method
    {
        get
        {
            var res = System.Reflection.MethodBase.GetCurrentMethod().Name;
            return res;
        }
    }
}

Мне нужно, чтобы свойство Method возвращало строковое представление имени свойства Name, когда я делаю такой вызов:

var propName = new News().Name.Method;

Как я могу этого добиться? Спасибо за уделенное время!


person CodeDemen    schedule 11.03.2013    source источник
comment
stackoverflow.com/questions/4657311/   -  person SpaceBison    schedule 11.03.2013
comment
Может быть, вам нужно найти хостинг PropertyInfo из MethodInfo геттера/сеттера?   -  person Jeppe Stig Nielsen    schedule 11.03.2013
comment
Я не думаю, что это возможно. Как экземпляр LocaleValues мог узнать, что он был найден через свойство с именем Name? Код, который у вас есть, вероятно, каждый раз возвращает get_Method? Может быть, вам следует заставить ваш установщик Name изменить параметр, который он принимает в (value), чтобы записать имя?   -  person Jeppe Stig Nielsen    schedule 11.03.2013


Ответы (1)


Если вы действительно имеете в виду свойство current (название вопроса):

public static string GetCallerName([CallerMemberName] string name = null) {
    return name;
}
...

public string Foo {
    get {
        ...
        var myName = GetCallerName(); // "Foo"
        ...
    }
    set { ... }
}

это передает работу компилятору, а не среде выполнения, и работает независимо от встраивания, обфускации и т. д. Обратите внимание, что для этого требуется директива using using System.Runtime.CompilerServices;, C# 5 и .NET 4.5 или аналогичная.

Если вы имеете в виду пример:

var propName = new News().Name.Method;

тогда это невозможно напрямую из этого синтаксиса; .Name.Method() будет вызывать что-то (возможно, метод расширения) для результата .Name, но это всего лишь другой объект, и он ничего не знает о том, откуда он взялся (например, свойство Name). В идеале, чтобы получить Name, проще всего использовать деревья выражений.

Expression<Func<object>> expr = () => new News().Bar;

var name = ((MemberExpression)expr.Body).Member.Name; // "Bar"

который может быть инкапсулирован как:

public static string GetMemberName(LambdaExpression lambda)
{
    var member = lambda.Body as MemberExpression;
    if (member == null) throw new NotSupportedException(
          "The final part of the lambda is not a member-expression");
    return member.Member.Name;
}

i.e.

Expression<Func<object>> expr = () => new News().Bar;
var name = GetMemberName(expr); // "Bar"
person Marc Gravell    schedule 11.03.2013
comment
Может быть, я чего-то не понимаю.... или написал что-то не так в своем вопросе, но как я могу использовать его, чтобы узнать точное имя моего свойства внутри LocaleValues? Мне нужно сделать так, чтобы когда я вызываю News.Name.Method, чем LocalValues знал, что он назван как Name, а когда я вызываю News.Body.Method, чем он вызывается как Body, то же самое с другими классами, которые имеют свойство типа LocalValues... И мне очень жаль мой плохой английский :( - person CodeDemen; 11.03.2013
comment
Это особенно полезно для MVVM в WPF, поскольку вместо того, чтобы говорить NotifyPropertyChanged("Foo"), вы можете использовать этот атрибут и просто сказать NotifyPropertyChanged(). - person Sellorio; 04.07.2016