Получить имя свойства класса - PullRequest
11 голосов
/ 30 сентября 2008

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

Me.TextEdit4.DataBindings.Add (New System.Windows.Forms.Binding ("EditValue", Me.MyClassBindingSource, "MyClassProperty", True))

Это работает нормально, но если я изменю имя свойства класса, компилятор, очевидно, не предупредит меня.

Я хотел бы иметь возможность получить имя свойства по отражению, но я не знаю, как указать имя свойства, которое я хочу (я знаю только, как выполнить итерацию среди всех свойств класса)

Есть идеи?

Ответы [ 6 ]

8 голосов
/ 30 сентября 2008

Если вы используете C # 3.0, есть способ получить имя свойства динамически, без жесткого кодирования.

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

Где BindingSourceType - имя класса вашего экземпляра объекта источника данных.

Затем вы можете использовать лямбда-выражение для выбора свойства, которое вы хотите связать, строго типизированным способом:

this.textBox.DataBindings.Add(GetPropertyName(o => o.MyClassProperty),
                              this.myDataSourceObject,
                              "Text");

Это позволит вам безопасно выполнить рефакторинг вашего кода, не затрачивая все свои связывающие данные вещи. Но использование деревьев выражений - это то же самое, что использование отражения с точки зрения производительности.

Предыдущий код довольно уродливый и непроверенный, но вы поняли идею.

6 голосов
/ 30 сентября 2008

Вот пример того, о чем я говорю:

[AttributeUsage(AttributeTargets.Property)]
class TextProperyAttribute: Attribute
{}

class MyTextBox
{
    [TextPropery]
    public string Text { get; set;}
    public int Foo { get; set;}
    public double Bar { get; set;}
}


static string GetTextProperty(Type type)
{
    foreach (PropertyInfo info in type.GetProperties())
    {
        if (info.GetCustomAttributes(typeof(TextProperyAttribute), true).Length > 0)
        {
            return info.Name;
        }
    }

    return null;
}

...

Type type = typeof (MyTextBox);

string name = GetTextProperty(type);

Console.WriteLine(name); // Prints "Text"
3 голосов
/ 30 сентября 2008

По иронии судьбы, вы ожидаете, что вы предоставите имя свойства, чтобы получить информацию :)

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

0 голосов
/ 30 сентября 2008

1) Укажите точное имя свойства, которое вы хотите, и сохраните его таким образом

2) Напишите тест с именем этого свойства.

0 голосов
/ 30 сентября 2008

Вы можете отразить тип, но вы не можете отразить его членов, кроме как по имени.

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

Я считаю, что изменение имени вызовет исключение во время выполнения, но я не уверен на 100%, в любом случае это, вероятно, лучшая возможность.

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

0 голосов
/ 30 сентября 2008

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

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