2013-03-07 3 views
3

Мне просто интересно узнать о практике кодирования данных привязки к выпадающему знаку (или другому объекту, который можно связать). Предположим, я создал объект, и я хочу добавить их в список со списком. Итак, я создаю свой объект и даю ему некоторые свойства.Код привязки и рефакторинга

public class ObjectForList 
{ 
    public string ObjectName { get; set; } 
    public int ObjectID { get; set; } 
    public string SomeOtherProperty { get; set; } 
    public ObjectForList() 
    { 
    } 
} 

Итак я делаю их список и установить его в качестве источника для моего комбинированного окна

List<ObjectForList> myObjects= new List<ObjectForList> { ...bunch of ObjectForList objects...}; 

comboBox1.DataSource = myObjects; 
comboBox1.DisplayMember = "ObjectName"; 
comboBox1.ValueMember = "ObjectID"; 

Вот как я понимаю, это должно быть сделано, по крайней мере. Я вижу эту реализацию на всех объяснениях, которые я нашел в сети.

Но наличие элементов отображения и значения как жестко закодированных строк имен переменных кажется мне неспокойным. Если кто-то приходит в Visual Studio спустя годы и реорганизует свойство ObjectID (быть «MyID» или что-то в этом роде), то привязка combobox будет ломаться. И он все равно будет компилироваться, поэтому никто не заметил бы до загрузки формы с помощью combobox. Кроме того, вы не сможете найти использование этого свойства, используя «Найти ссылки», поскольку это просто строка.

Что люди думают об этом? Как это использовать и по-прежнему поддерживать ваш код?

+4

Вы абсолютно правы. Авто-рефакторинг VS не справится с этим, и если у вас много ComboBox, это может быть немного хлопот. Насколько я знаю, нет отличного способа решить эту проблему ... –

+1

Большой вопрос, ОП. Чтобы опираться на комментарий Адама и ваш пост, кто-нибудь знает, может ли Решарр справиться с таким случаем? – Brian

+2

Почасовая поездка в магазин спиртных напитков, поскольку головоломка - хороший вопрос. – Greg

ответ

1

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

Expression<Func<ObjectForList, String>> exp = o => o.ObjectName; 
MemberExpression member = (MemberExpression)exp.Body; 
comboBox1.DisplayMember = member.Member.Name; 

Конечно вы, вероятно, нужно инкапсулировать, что в качестве метода, поэтому вам не придется повторно написать что-то вдоль этих линий каждый раз ,

class Tools 
{ 
    public static String GetMemberName<ObjType, MemberType>(Expression<Func<ObjType, MemberType>> expression) 
    { 
     MemberExpression member = (MemberExpression)expression.Body; 
     return member.Member.Name; 
    } 
} 

Итак вы смогли бы использовать

List<ObjectForList> myObjects= new List<ObjectForList> { ...bunch of ObjectForList objects...}; 

comboBox1.DataSource = myObjects; 
comboBox1.DisplayMember = Tools.GetMemberName<ObjectForList, String>(o => o.Objectname); 
comboBox1.ValueMember = Tools.GetMemberName<ObjectForList, int>(o => o.ObjectID); 

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

2

Может быть сделано без прохождения элемента элемента, а также правильно?

comboBox1.ValueMember = GetPropName(() => ObjectForListObject.ObjectID); 

    public static string GetPropName<T>(Expression<Func<T>> propExp) 
    { 
    return (propExp.Body as MemberExpression).Member.Name; 
    } 
2

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

public static class Constants 
{ 
    public static class MyObjects 
    { 
     public const string DisplayMember = "ObjectName"; 
     public const string ValueMember = "ObjectID"; 
    } 
} 

Используйте этот путь:

comboBox1.DataSource = myObjects; 
comboBox1.DisplayMember = Constants.MyObjects.DisplayMember; 
comboBox1.ValueMember = Constants.MyObjects.ValueMember; 

Теперь, автоматический рефакторинг имен свойств все равно не поможет. Однако, имея класс константы означает 2 хороших вещи:

  1. Если вы используете одни и те же строки в нескольких местах, то вам нужны только обновить его здесь, в одном месте .. не много
  2. Любых будущих разработчиков должен знать, что вы ТОЛЬКО держите свои жестко закодированные строки в ОДНОМ месте. Итак, они идут в Константы, видят, что там, и если вы хорошо написали вещи, то все, что нужно изменить, должно быть очевидно для них.
Смежные вопросы