Подтвердить что ты не робот

Получить имя свойства класса

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

Me.TextEdit4.DataBindings.Add(новый файл System.Windows.Forms.Binding( "EditValue", Me.MyClassBindingSource, "MyClassProperty", True))

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

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

Любая идея?

4b9b3361

Ответ 1

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

[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"

Ответ 2

Если вы используете С# 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");

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

Предыдущий код довольно уродливый и неконтролируемый, но вы получаете идею.

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

2) Напишите тест, включающий это имя свойства.