日期时间数组和对象数组问题

3

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

我的搜索表达式构造函数如下所示(有些被省略了):

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

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

当传递以下内容时,这两种方法都能正常工作:

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

然而,当涉及到传递日期时间信息时,我开始遇到一些问题。

当数据根据类型(日期时间、数字或字符串)分开处理并检查有效性后,它们将被存储到数组中以便于传递到正确的表达式中,如下所示:

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);

它是如何失败的?编译错误?运行时异常?还是出现了意外行为?提供任何错误的详细信息都会有所帮助。 - gnomed
只是一个无效参数错误 - 当尝试传递 DateTime[] 时。 - Rion Williams
3个回答

2
为什么我可以将单个DateTime值作为对象传递?
有一个从DateTime(值类型)到object的隐式装箱转换可用。
但是我无法将DateTime []作为对象[]传递?
从DateTime []到object []没有可用的隐式转换。尽管在C#中数组通常 具备协变性(例如,从string []到object []存在隐式转换),但这并不适用于值类型的数组——协变转换当前需要是保持标识的转换,并且有充分的理由。

谢谢Ani - 我很感激(也感谢你发的关于协方差的帖子!) - Rion Williams

1

这是天生的协变性问题,其中数组不支持 数组不支持值类型

Eric Lippert此处有一篇非常好的文章。


解决方案

将方法签名更改为IEnumerable<object>


感谢Aliostad的文章!我最初考虑使用IEnumerable,但我想当我选择使用数组时,我可能感觉很经典。非常感谢! - Rion Williams
没问题。希望能对你有所帮助。 - Aliostad

0

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

你可以编写静态扩展/Linq来将DateTime[]转换为object[]。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接