2013-08-13 4 views
1

У меня есть класс, имеющий около 40 объектов (я не говорю об этом, это соответствует спецификации). Все свойства имеют настраиваемые «установленные» методы.Как переписать этот блок кода?

Существует одна немного сложная проверка, которую я должен наложить на все «установленные» методы. Я уже отделил проверку на отдельный метод, позвонит ему

CommonValidate(string PropertyName, string PropertyValue).

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

public string Property1 
    { 
     set 
     { 
      this.field1 = value; 
      CommonValidate(Property1, this.field1); 
     } 
    } 

    public DateTime Property2 
    { 
     set 
     { 
      this.field2 = value.ToString("ddMMyy");; 
      CommonValidate(Property2, this.field2); 
     } 
    } 

    public string Property3 
    { 
     set 
     { 
      this.field3 = value; 
      CommonValidate(Property3, this.field3); 
     } 
    } 

Это так, как я только что вставил метод CommonValidate призывающего всего 40 «установить» методы , Я считаю, что это очень неэффективно, представьте, есть ли запрос изменения количества аргументов в методе CommonValidate.

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

+3

http://codereview.stackexchange.com/ – wudzik

+3

Это не вопрос с кодовым обзором. –

+0

передают только «это» в CommonValidate? –

ответ

1

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

void ValidateAndSet(string propName, object newValue){ 
    foreach(var prop in propsClass.GetType().GetProperties().Where(p => p.Name == propName)) 
    { 
     if(CommonValidate(prop, newValue)) 
      prop.GetSetMethod().Invoke(propsClass, new object[] { newValue}); 
     return; // Only one anyways 
    } 
    Logger.Log("Failed to find the property '{0}' to set '{1}'", propName, newValue); 
} 

propsClass является объект класса, что свойства в. Может это сделать в классе или передать его в функцию в качестве другого параметра.

0

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

Однако, если вы не идете по этому маршруту, одна вещь, которую я бы изменил, это использование строк в CommonValidate, а вместо этого используйте System.Linq.Expression.

Я бы переписать его, чтобы выглядеть примерно так:

static void CommonValidate<T>(Expression<Func<MyClass, T>> propertySelector, T newValue) //replace MyClass with name of current class 
{ 
    MemberExpression memberExpression = propertySelector.Body as MemberExpression; 
    if (memberExpression == null) 
     throw new ArgumentException("propertySelector") 

    string propertyName = MemberExpression.Member.Name; 

    //validation code, e.g. 

    CommonValidate(propertyName, newValue.ToString()) 
} 

Тогда сеттеры будет выглядеть

public string Property1 
{ 
    set 
    { 
     this.field1 = value; 
     CommonValidate(c => c.Property1, value); 
    } 
} 

Преимущество этого является то, что если вы измените имя свойства на ваш класс, он становится ошибкой времени компиляции, чтобы не изменить вызов CommonValidate. Если вы идете по этому маршруту, вы должны использовать что-то похожее, чтобы настроить свою проверку: я предполагаю, что у вас есть конструктор, где-то заполняющий Dictionary<string, Func<string, bool> - используйте код, аналогичный этому в новом CommonValidate выше, чтобы вместо этого получить ключи имени свойства ,

Смежные вопросы