Как получить имя свойства из свойства в C # (2.0)

Я знаю, что у меня может быть атрибут, но это больше работы, чем я хочу ... и недостаточно.

Я хочу сделать что-то вроде

class Whotsit
{
    private string testProp = "thingy";

    public string TestProp 
    {
        get { return testProp; }
        set { testProp = value; }
    }

}

...

Whotsit whotsit = new Whotsit();
string value = GetName(whotsit.TestProp); //precise syntax up for grabs..

где я ожидаю, что значение будет равно "TestProp"

но я не могу на всю жизнь найти правильные методы отражения, чтобы написать метод GetName ...

РЕДАКТИРОВАТЬ: Почему я хочу это сделать? У меня есть класс для хранения настроек, прочитанных из таблицы «имя», «значение». Это заполняется обобщенным методом, основанным на рефлексии. Я бы очень хотел написать обратное ...

/// <summary>
/// Populates an object from a datatable where the rows have columns called NameField and ValueField. 
/// If the property with the 'name' exists, and is not read-only, it is populated from the 
/// valueField. Any other columns in the dataTable are ignored. If there is no property called
/// nameField it is ignored. Any properties of the object not found in the data table retain their
/// original values.
/// </summary>
/// <typeparam name="T">Type of the object to be populated.</typeparam>
/// <param name="toBePopulated">The object to be populated</param>
/// <param name="dataTable">'name, 'value' Data table to populate the object from.</param>
/// <param name="nameField">Field name of the 'name' field'.</param>
/// <param name="valueField">Field name of the 'value' field.</param>
/// <param name="options">Setting to control conversions - e.g. nulls as empty strings.</param>

public static void PopulateFromNameValueDataTable<T>
        (T toBePopulated, System.Data.DataTable dataTable, string nameField, string valueField, PopulateOptions options)
    {
        Type type = typeof(T);
        bool nullStringsAsEmptyString = options == PopulateOptions.NullStringsAsEmptyString;

        foreach (DataRow dataRow in dataTable.Rows)
        {
            string name = dataRow[nameField].ToString();
            System.Reflection.PropertyInfo property = type.GetProperty(name);
            object value = dataRow[valueField];

            if (property != null)
            {
                Type propertyType = property.PropertyType;
                if (nullStringsAsEmptyString && (propertyType == typeof(String)))
                {
                    value = TypeHelper.EmptyStringIfNull(value);
                }
                else
                {
                    value = TypeHelper.DefaultIfNull(value, propertyType);
                }

                property.SetValue(toBePopulated, System.Convert.ChangeType(value, propertyType), null);
            }
        }
    }

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: я только что написал код, имею экземпляр Whotsit и хочу получить текстовую строку свойства 'TestProp'. Мне кажется, это немного странно, я могу просто использовать литерал «TestProp» - или в случае с функцией от класса до данных я буду в цикле foreach PropertyInfos. Мне было просто любопытно...

Оригинальный код имел строковые константы, которые я нашел неуклюжим.

 Jeffrey Knight13 мая 2009 г., 17:45
Смотрите <a href = "stackoverflow.com/questions/855337/...>
 nawfal27 апр. 2013 г., 16:51
Вы можете получить ответ здесьstackoverflow.com/a/1225702/661933

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

Решение Вопроса

Нет, ничего не поделаешь. Выражениеwhotsit.TestProp оценит недвижимость. То, что вы хотите, это мифический оператор "infoof":

// I wish...
MemberInfo member = infoof(whotsit.TestProp);

Таким образом, вы можете использовать отражение только для получения свойства по имени, а не из кода. (Или, конечно, получите все свойства. Тем не менее, это не поможет вам с вашим образцом.)

Одна альтернатива - использовать дерево выражений:

Expression<Func<string>> = () => whotsit.TestProp;

затем изучите дерево выражений, чтобы получить свойство.

Если ничего из этого не помогает, возможно, вы могли бы рассказать нам больше о том, зачем вам эта функциональность?

что это возможно, единственный способ сделать это - перебрать свойства:

class TestClass
{
    private string _field;

    public string MyProperty
    {
        get { return _field; }
    }
}
class Program
{
    static void Main(string[] args)
    {
        TestClass test = new TestClass();
        PropertyInfo[] info = test.GetType().GetProperties();
        foreach(PropertyInfo i in info)
            Console.WriteLine(i.Name);
        Console.Read();
    }
}
 kpollock23 дек. 2008 г., 14:03
что все еще не даст мне возможность получить имя свойства из его экземпляра.

очень быстро и очень грязно

class Program
{
    static void Main()
    {
        string propertyName = GetName(() => AppDomain.CurrentDomain);
        Console.WriteLine(propertyName); // prints "CurrentDomain"
        Console.ReadLine();
    }

    public static string GetName(Expression<Func<object>> property)
    {
        return property.Body.ToString().Split('.').Last();
    }
}

Обновить: Я только что понял, чтоДжон Скит (кто-нибудь удивился? :) уже рассмотрел эту возможность, но я оставлю здесь свой ответ на всякий случай, если кому-то будет интересен какой-то пример для начала.

 lubos hasko23 дек. 2008 г., 14:26
Я знаю, но это хороший общий вопрос, и кто-то с .NET 3.5 может быть заинтересован в этом.
 kpollock23 дек. 2008 г., 14:31
Я согласен, мне это не очень полезно, но, возможно, пригодится другим, кто придет посмотреть.
 Marc Gravell23 дек. 2008 г., 14:24
Также необходим .NET 3.5 (OP состояния 2.0)

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

Нерабочий код ниже:

Whotsit w = new Whotsit();
XmlSerializer xs = new XmlSerializer(w.TestProp.GetType());
TextWriter sw = new StreamWriter(@"c:\TestProp.xml");
xs.Serialize(sw, w.TestProp);
sw.Close();

что вы пытаетесь сделать, невозможно. Используя отражение, вы можете:

Получить информацию о свойстве, поле или методе из его строкового имени.Получить список всех свойств, полей или методов для данного типа.

При вызове вашего метода GetName передается строка. GetMethod узнает о строке, но не сохраняет метаданные свойства источника.

Из интереса, почему вы пытаетесь это сделать?

GetProperties для класса Type даст вам список свойств этого типа.

Type t = whotsit.GetType();
PropertyInfo[] pis = t.GetProperties();
 kpollock23 дек. 2008 г., 14:01
правда, но не очень полезно для того, что я хочу сделать, так как это строка имени, которое я после ...

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

Это приводит меня к мысли, что у вас есть какая-то ссылка на недвижимость. Как вы получили эту ссылку? Каков его тип? Не могли бы вы предоставить пример кода? Если это объект PropertyInfo, у вас уже есть то, что вам нужно; поскольку, похоже, это не так, мы имеем дело с чем-то другим, и мне было бы очень интересно узнать, что выделать надо работать с.

Постскриптум Простите, что выглядело глупо: рано, мне не хватает кофе, и передо мной нет моей IDE. : - /

 kpollock23 дек. 2008 г., 14:36
Я только в коде, есть экземпляр Whotsit, и я хочу получить текстовую строку свойства 'TestProp'. Мне кажется, это немного странно, я могу просто использовать литерал «TestProp» - или в случае с функцией от класса до данных я буду в цикле foreach PropertyInfos. Мне было просто любопытно.

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