Проблемы с датой-временем[] и объектом[]

#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. надеюсь, это поможет 🙂