I recently was working with some dynamic Search Expressions and ran into a bit of an issue when I was attempting to search for multiple Date/Times.
My SearchExpression constructors resemble the following (some omitted for brevity):
public SearchExpression(string propertyName,
ComparisonOperator comparisonOperator,
object value) {...}
and
public SearchExpression(string propertyName,
ComparisonOperator comparisonOperator,
object[] values,
BooleanOperator innerBooleanOperator) {...}
Both of these work as they should when passed the following :
- Strings
- Numbers (or any numerical data)
However, when it comes to passing DateTime information, I began to encounter some problems.
I have all of my data seperated when it comes in based on the type (DateTime, Numerical or String) and ch开发者_StackOverflow中文版eck for validity, they are then stored into array to pass to the proper expressions, like so:
object[] stringParameters;
object[] numericalParameters;
DateTime[] dateParameters;
All of these work when I pass in any of the above, with the exception of an array of DateTime parameters.
So my question, which leaves me feeling a bit foolish, is why can I pass a single DateTime value as an object, but am unable to pass an DateTime[]
as an object[]
.
Example:
DateTime[] dateParameters;
//This works fine
new SearchExpression("DateTime", ComparisonOperator.Equals, dateParameters[0]);
//This fails to work
new SearchExpression("DateTime", ComparisonOperator.Equals, dateParameters,
BooleanOperator.Or);
Why can I pass a single DateTime value as an object?
There is an implicit boxing conversion available from DateTime
(a value-type) to object
.
But am unable to pass an DateTime[] as an object[]?
There is no implicit conversion available from a DateTime[]
to object[]
. Although arrays in C# exhibit covariance in general (for example, there is an implicit conversion from string[]
to object[]
), this does not extend to arrays of value-types - covariant conversions are currently required to be identity-preserving conversions, with good reason.
This is inherently a problem of Covariance
which arrays do not support arrays do not support for value types.
Eric Lippert has a very good post on that here.
Solution
Change method signature to IEnumerable<object>
.
you can pass/cast DateTime[] as object as well, but not as object[] because it needs casting/converting for each item in the array. compiler will complain about the latter.
you can write Static Extension/Linq to convert DateTime[] into object[].
when function is expecting object[], it is not expecting array of objects.
when function is expecting object, you can pass DateTime, because DateTime being of type "struct" inherits from object. hope it helps :)
精彩评论