DateTime[] and Object[] Issues

本文关键字:Issues Object and DateTime | 更新日期: 2023-09-27 17:48:56

我最近正在使用一些动态搜索表达式,当我试图搜索多个日期/时间时遇到了一点问题。

我的SearchExpression构造函数类似于以下(为简洁起见省略了一些):

public SearchExpression(string propertyName, 
                        ComparisonOperator comparisonOperator, 
                        object value) {...}

public SearchExpression(string propertyName, 
                        ComparisonOperator comparisonOperator, 
                        object[] values, 
                        BooleanOperator innerBooleanOperator) {...}

当传递以下命令时,它们都可以正常工作:

    字符串
  • 数字(或任何数字数据)

然而,在传递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);

DateTime[] and Object[] Issues

为什么我可以传递一个DateTime作为对象的价值?

存在从DateTime(一个值类型)到object的隐式装箱转换。

但是我无法传递DateTime[]作为一个对象[]吗?

没有从DateTime[]object[]的隐式转换。虽然c#中的数组通常表现为协方差(例如,从string[]object[]有一个隐式转换),但并没有扩展到值类型的数组——协变转换目前要求是保持恒等的转换,这是有充分理由的。

这是Covariance固有的问题,数组不支持数组不支持值类型。

Eric Lippert在这里有一个非常好的帖子。


<标题> 解决方案

修改方法签名为IEnumerable<object>

您也可以将DateTime[]作为对象传递/强制转换,但不能作为object[]传递/强制转换,因为它需要对数组中的每个项进行强制转换。编译器会报错后者。

你可以写Static Extension/Linq来把DateTime[]转换成object[]。

当函数期望对象[]时,它不是期望对象数组。

当函数期望对象时,你可以传递DateTime,因为DateTime的类型是"struct"继承自object。希望能有所帮助:)