Получить имя свойства внутри сеттера

Я хочу сохранить свойство между постбэками в приложении ASP.Net. В данный момент занимаюсь этим:

<code>public int MyIndex
{
    get
    {
        return (int)Session[ToString() + "MyIndex"];
    }
}
</code>

но предпочел бы что-то вроде:

<code>public int MyIndex
{
    get
    {
        return (int)Session[ToString() + #code_that_returns_property_name#];
    }
}
</code>

Setter опущен, но он просто помещает значение в Session, используя ту же строку. Есть ли способ использовать отражение или другое лучшее решение?

 JMD24 нояб. 2014 г., 16:40
Похоже, у нас наконец-то естьsyntactic candy coming чтобы решить эту проблему для нас: «Часто вам нужно предоставить строку, которая называет некоторый программный элемент: когда выдается исключение ArgumentNullException, вы хотите назвать виновный аргумент; когда вы вызываете событие PropertyChanged, вы хотите присвоить имя измененному свойству и т. д. & quot;if (x == null) throw new ArgumentNullException(nameof(x));

Ответы на вопрос(6)

не существует простого способа сделать то, что вы хотите. я думаю, выmuch лучше с кодом, который вы уже написали.

Edit: This answer has received quite a few downvotes and I do understand why. While it is possible to do what the OP wants to do perhaps we should all stop and think whether or not it is advisable to do so. To paraphrase the immortal words of Доктор Ян МалкомТо, что вы можете сделать что-то, не означает, что вы должны это делать.

 25 июн. 2009 г., 17:33
Почему голосование за? это самый разумный ответ ... :) +1 от меня.
 23 нояб. 2015 г., 22:22
Я мог бы опровергнуть это из-за того, что «не существует простого способа сделать то, что вы хотите». Это вводит в заблуждение.
 14 нояб. 2014 г., 18:38
+1 за это и принятый ответ. Я могу понять, почему OP хотел бы сделать это, и смягчающий фактор: если рассматриваемое свойство является лишь одним из 40, то есть кое-что, что нужно сказать для одной реализации, которая отделена от 40 жестко-закодированного свойства. имена. Смягчающий фактор является, конечно же, если ОП знает, что эти свойства только установить один или небольшое количество раз, производительность на этом уровне является спорным. Откажитесь от преждевременной оптимизации.
 25 июн. 2009 г., 18:35
+1 от меня тоже, это безумная идея. Если вы обнаружите, что вам приходится много делать, а имя постоянно меняется, поэтому управление им становится бременем, а затем используйте файл .tt для кодирования объявлений свойств или чего-то в этом роде.

ViewState собственность вашего контроля:

public int MyIndex {
    get { 
        object index = ViewState["MyIndex"];
        return (null == index) ? -1 : (int)index;
    }
    set {
        ViewState["MyIndex"] = value;
    }
}

чтобы получить имя члена. Это немного скакать, но это работает. Вот код

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector)
{
    var memberExpression = propertySelector.Body as MemberExpression;
    if (memberExpression != null)
    {
        return memberExpression.Member.Name;
    }
    else
    {
       return string.empty;    
    }
}

С этим кодом вы можете сделать следующее

return (int)Session[ToString() + GetPropertyName(MyIndex)];

Код безжалостно украден из ответа Ромен в следующей ветке

Get class property name
 25 июн. 2009 г., 17:31
Какое элегантное решение! +1
 Steve Macdonald25 июн. 2009 г., 17:43
Не удается разрешить символ «BindingSourceType» Это проект ASP.Net 3.5 ...
 25 июн. 2009 г., 18:22
Если вы читаете исходный ответ из другого потока, он говорит, что BindingSourceType - это имя класса, которое содержит свойство. Вам нужно использовать имя класса, которому принадлежит свойство MyIndex.

чтобы вернуть имя текущего метода:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name];
    }
}

Поскольку свойства реализованы как внутренние методы, они будут возвращать имя, подобное & quot; get_MyIndex & quot ;. Если вы не хотите & quot; get_ & quot; часть, вы можете вычленить несколько символов:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name.Substring(4)];
    }
}

CallerMemberName это намного быстрее, и его можно легко скопировать и вставить для дополнительных свойств.

private static object GetSessionValue([CallerMemberName]string propertyName = "") 
{
    return Session[propertyName];
}

private static void SetSessionValue(object value, [CallerMemberName]string propertyName = "") 
{
    Session[propertyName] = value;
}

public int MyIndex
{
    get { return (int)GetSessionValue(); }
    set { SetSessionValue(value); }
}
 14 авг. 2016 г., 13:37
Этот ответ - лучший способ, поскольку он работает во время компиляции, а не во время выполнения.
Решение Вопроса
public static int Dummy {
    get {
        var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4);
        Console.WriteLine(propertyName);
        return 0;
    }
}
 15 апр. 2016 г., 17:48
Смотрите мой ответ, который использует CallerMemberName для решения проблемы скорости.
 Steve Macdonald25 июн. 2009 г., 17:49
Нет, это сработало. Не уверен, откуда это исключение. Работает нормально сейчас. Как раз то, что мне было нужно.
 Steve Macdonald25 июн. 2009 г., 17:30
GetCurrentMethod () возвратил System.ArgumentException для меня ...
 25 июн. 2009 г., 19:01
В дополнение к другим комментариям этот метод будет в сотни (тысячи?) Раз медленнее, отражение не является дешевым. Это может не беспокоить ОП, но любой, кто задумывается над этим, должен знать об этом. (простой тест на моей машине, версия отражения заняла 71 секунду для 10000000 вызовов, версия с жестким кодом заняла 0,8 секунды)
 25 июн. 2009 г., 18:37
Ради любви к Богу, нет! Результат в пять раз длиннее и в 100 раз более непонятен, чем то, что он заменил! Если вы не собираетесь постоянно передумать, как назвать это свойство, это нелепая идея. (... ПО МОЕМУ МНЕНИЮ)

Ваш ответ на вопрос