#c# #datetime #object #casting
#c# #datetime #объект #Кастинг
Вопрос:
Недавно я работал с некоторыми выражениями динамического поиска и столкнулся с небольшой проблемой при попытке поиска по нескольким датам / временам.
Мои конструкторы SearchExpression похожи на следующие (некоторые опущены для краткости):
public SearchExpression(string propertyName,
ComparisonOperator comparisonOperator,
object value) {...}
и
public SearchExpression(string propertyName,
ComparisonOperator comparisonOperator,
object[] values,
BooleanOperator innerBooleanOperator) {...}
Оба они работают должным образом при передаче следующего :
- Строки
- Числа (или любые числовые данные)
Однако, когда дело доходит до передачи информации DateTime, я начал сталкиваться с некоторыми проблемами.
При поступлении все мои данные разделяются на основе типа (DateTime, числовой или строковый) и проверяются на достоверность, затем они сохраняются в массиве для передачи в соответствующие выражения, например, так:
object[] stringParameters;
object[] numericalParameters;
DateTime[] dateParameters;
Все это работает, когда я передаю любой из вышеперечисленных параметров, за исключением массива параметров DateTime.
Итак, мой вопрос, который заставляет меня чувствовать себя немного глупо, заключается в том, почему я могу передать единственное значение DateTime как объект, но не могу передать DateTime[]
как object[]
.
Пример:
DateTime[] dateParameters;
//This works fine
new SearchExpression("DateTime", ComparisonOperator.Equals, dateParameters[0]);
//This fails to work
new SearchExpression("DateTime", ComparisonOperator.Equals, dateParameters,
BooleanOperator.Or);
Комментарии:
1. Как именно происходит сбой? Ошибка компиляции? Исключение во время выполнения? или неожиданное поведение? было бы полезно получить подробную информацию о любых ошибках.
2. Это была просто ошибка с недопустимыми аргументами — при попытке передать DateTime[].
Ответ №1:
Почему я могу передать единственное значение DateTime в качестве объекта?
Доступно неявное преобразование бокса из DateTime
(типа значения) в object
.
Но я не могу передать DateTime[] как object[]?
Недоступно неявное преобразование из a DateTime[]
в object[]
. Хотя массивы в C # демонстрируют ковариацию в целом (например, существует неявное преобразование из string[]
в object[]
), это не распространяется на массивы типов значений — ковариантные преобразования в настоящее время требуются для преобразования с сохранением идентичности, и на то есть веские причины.
Комментарии:
1. Спасибо, Ани — я ценю это (также спасибо за пост о ковариации!)
Ответ №2:
Это неотъемлемо связано с тем, что Covariance
какие массивы не поддерживают массивы не поддерживают типы значений.
У Эрика Липперта есть очень хороший пост по этому поводу здесь.
Решение
Измените сигнатуру метода на IEnumerable<object>
.
Комментарии:
1. Спасибо за статью, Алиостад! Изначально я рассматривал возможность использования IEnumerable, но, полагаю, я чувствовал себя классическим при выборе использования массива. Очень признателен!
2. Проблем нет. Надеюсь, это помогло вам.
Ответ №3:
вы также можете передавать / приводить DateTime[] как object, но не как object[], потому что для этого требуется приведение / преобразование для каждого элемента в массиве. компилятор будет жаловаться на последнее.
вы можете написать статическое расширение / Linq для преобразования DateTime[] в object[].
когда функция ожидает object[], она не ожидает массив объектов.
когда функция ожидает объект, вы можете передать DateTime, потому что DateTime, имеющий тип «struct», наследуется от object. надеюсь, это поможет 🙂