Создание дерева выражений с помощью TryParse и Convert C #

1

У меня есть список объектов, которые я хочу фильтровать с помощью выражения, которое создается во время выполнения. Окончательное выражение содержит несколько условий, в сочетании с && или ||, заключенными в предложения. Каждое условие выглядит следующим образом:

x => x.ValueType == 1 && x.Value == "abc"

Как вы можете видеть, есть только 2 свойства для проверки. Если ValueType равен 1, Value всегда является строкой. Если ValueType равно 2, Value всегда должно содержать строку, которая может быть преобразована в double.

Value имеет тип string. Если условие использует оператор больше, чем (>), Value нужно преобразовать в double. Поэтому в этом случае тело выражения выглядит так:

$x.ValueType == 2 & .Call System.Convert.ToDouble($x.Value) > 5

Пока здесь, все работает как ожидалось.

Проблема:

Если я использую выражение выше (ValueType == 2 && Value> 5) с этим списком:

var list = new List<Item>();
list.Add(new Item { ValueType = 1, Value = "abc" });
list.Add(new Item { ValueType = 1, Value = "def" });
list.Add(new Item { ValueType = 2, Value = "25" });
list.Add(new Item { ValueType = 2, Value = "37" });
var results = list.AsQueryable().Where(expression);

Я получаю FormatException: строка ввода не была в правильном формате. Я думал, что он не будет пытаться преобразовать элементы 1 и 2 в double, потому что условие ValueType уже возвращает false. Но я был неправ.

Должен ли я использовать TryParse все эти значения, прежде чем преобразовывать их в double, или использовать свойства для каждого типа значений вместо одного свойства string? Я попытался вставить TryParse в дерево выражений, но я не знаю, как...

Изменение объектной модели на несколько свойств вызовет много изменений, поэтому я хочу избежать этого "решения".

Я уверен, кто-то здесь знает, как справиться с этой проблемой. Или, по крайней мере, может указать мне в правильном направлении.

Теги:
expression-trees

1 ответ

0
Лучший ответ

Используйте && вместо & для оценки короткого замыкания на С#.

void Main()
{
    Func<Item, bool> expression = x => x.ValueType == 2 && Convert.ToDouble(x.Value) > 5;
    var list = new List<Item>();
    list.Add(new Item { ValueType = 1, Value = "abc" });
    list.Add(new Item { ValueType = 1, Value = "def" });
    list.Add(new Item { ValueType = 2, Value = "25" });
    list.Add(new Item { ValueType = 2, Value = "37" });
    var results = list.AsQueryable().Where(expression);

    results.Dump();
}

public class Item
{
    public int ValueType {get;set;}
    public string Value {get;set;}
}
  • 0
    Спасибо! Это работает :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню