Выбор имен свойств на основе заданной строки

#c#

#c#

Вопрос:

Я хочу избежать дублирования кода. На данный момент я перебираю определенные «параметры», а затем на основе параметра вычисляю значение. Код выглядит примерно так:

 if (option == "A")
    result = (y[0].A - y[1].A) / (x[0].A - x[1].A);

if (option == "B")
    result = (y[0].B - y[1].B) / (x[0].B - x[1].B);

if (option == "C")
    result = (y[0].C - y[1].C) / (x[0].C - x[1].C);
 

Он делает то же самое для A, B и C — есть ли способ использовать строку «option» для выбора нужного свойства (A, B, C) из x и y?

x,y — это словарь <int, class>, и этот класс имеет свойства A,B,C, которые являются двойными

Комментарии:

1. Какой тип y и ‘x’? И A , B и C ?

2. x,y — это словарь <int, class>, и этот класс имеет свойства A,B,C, которые являются двойными

3. Без каких-либо дополнительных знаний я бы сначала выделил функцию «(a-b / c-d)» , а затем вместо строковой опции я бы сделал эти 3 отдельные функции. Все, что выше, для чего потребуется либо больше информации, либо больший редизайн.

Ответ №1:

Вы можете использовать Func , например ,:

 public double DoCalculation(Func<YourClassName, double> property, Foo y0, Foo y1, Foo x0, Foo x1)
{
    // Now we can call the Func on the objects passed in:
    return (property(y0) - property(y1)) / (property(x0) - property(x1));
}
 

Теперь назовите это так:

 result = DoCalculation(
    f => f.A, //<--- this is how you specify the property to call
    y[0], y[1], x[0], x[1]);
 

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

  1. Отражение происходит медленнее (хотя и не настолько сильно, как вы, вероятно, заметили бы в этом коде).
  2. Этот метод обеспечивает безопасность типов во время компиляции. Если вы используете отражение, вы не будете знать, что метод не существует в классе до времени выполнения.

Комментарии:

1. Вам все равно понадобится отражение, чтобы создать лямбда-выражение из option переменной. Или вам понадобится выражение switch case, которое преобразует строку в лямбда-выражение.

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

Ответ №2:

Если вы уверены, что ‘option’ всегда будет иметь то же значение, что и имя свойства, которое вы можете использовать:

 PropertyInfo info = typeof(<insert class y here>).GetProperty(option);
PropertyInfo info2 = typeof(<insert class x here>).GetProperty(option);
result = (double)info.GetValue(y[0]) - (double)info.GetValue(y[1]) / (double)info2.GetValue(x[0]) - (double)info2.GetValue(x[1])
 

Этот код не протестирован, но должен работать

Ответ №3:

Вы можете использовать отражение, как показано ниже :

 public double GetResult(string option) {

    var prop = x[0].GetType().GetProperty(option);

    var y0 = (double)prop.GetValue(y[0]);
    var y1 = (double)prop.GetValue(y[1]);

    var x0 = (double)prop.GetValue(x[0]);
    var x1 = (double)prop.GetValue(x[1]);

    var result = (y0-y1) / (x0-x1);
    return resu<
}