在C#2.0中使用Invoke调用时,参数从null转换为DateTime.MinValue

时间:2009-12-11 17:51:20

标签: c# reflection

我的代码有点像这样

public class MyObject
{
    private bool IsValidDay(ref DateTime theDate)
    {

    ...
    }
}


MethodInfo[] methods = myObjectInstance.GetType().GetMethod("IsValidDay", BindingFlags.Instance | BindingFlags.NonPublic);
object[] args = { null };
bool val = (bool)method.Invoke(myObjectInstance, args);

但是当调用该方法时,在IsValidDay方法中,theDate是DateTime.MinValue。这看起来非常奇怪 - 我可能期望抛出NullReferenceException而不是自动转换。

如果您想知道,这是单元测试中的代码。 (在使用中,该方法通常通过采用对象的公共方法调用)。

就其他一些后续调用的代码而言,DateTime.MinValue和null不是一回事,所以这有点问题。

任何线索?建议。

6 个答案:

答案 0 :(得分:3)

DateTime变量不能为null。它不是引用类型,因此不会有空引用异常。

你可以这样做:

private bool IsValidDay(ref DateTime? theDate)
{
   if(theDate.HasValue)...
}

这是一个关于可空类型的链接: http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx

我想我得到的是你的问题....在你的代码的情况下(特别是因为ref参数,你不能在ref或out的参数上有变化)。它必须传入DateTime对象。它不能是其他任何东西.....所以必须将null参数转换为某些东西以使函数起作用。

答案 1 :(得分:3)

来自MSDN

  

此数组中未使用值显式初始化的任何对象都将包含该对象类型的默认值。对于reference-type元素,此值为null。 对于值类型元素,此值为0,0.0或false,具体取决于特定元素类型。

DateTime的默认值为DateTime.MinValue

DateTime.MinValue == new DateTime() // true

这解释了当您使用DateTime.MinValue调用null时将null传递给该方法的原因。

请注意,在没有反射的情况下调用它时,无法将DateTime dt = null; // cannot assign null to value type obj.IsValidDay(ref dt); 传递给该方法:

null

所以我说你不需要用空引用来测试你的方法。


如果您希望自己的方法接受DateTime?,则可以将声明更改为private bool IsValidDay(ref DateTime? dt) { ... } ,正如其他人已经指出的那样:

{{1}}

答案 2 :(得分:2)

DateTime有值,建议您使用DateTime?(或Nullable<DataTime>)来支持空值

答案 3 :(得分:1)

Invoke()方法获取目标方法参数的值数组。根据MSDN,在目标方法调用之前,将使用默认值(在本例中为 DateTime.MinValue )初始化此数组中与 ref 参数对应的未初始化元素。 / p>

此外,在目标方法调用之后,将更新与 ref 参数对应的参数数组中的值。

在您的情况下,您不应使用 null 值测试该方法,因为它不是 DateTime 数据类型的有效值。

这是来自MSDN库中的Invoke方法doc的注释:

“如果此实例表示的方法或构造函数采用ref参数,则该参数不需要特殊属性,以便使用此函数调用方法或构造函数。此数组中未明确指定的任何对象使用值初始化将包含该对象类型的默认值。对于reference-type元素,此值为null。对于value-type元素,此值为0,0.0或false,具体取决于特定元素类型。

还找到了这个教程: Passing "ref" Parameters

答案 4 :(得分:0)

只有reference types可以为null。 DateTime(如int,bool,structs和enums)是Value Type。因此DateTime不能为null,就像枚举不能为null一样。您可以使用Nullable generic,将其声明为DateTime?。这将允许您将其检查为空。

答案 5 :(得分:-1)

最后,在这种情况下,我认为我会认为该方法实际上不需要对null进行测试,并且告诉自己通过反射调用方法并不总是会引发异常直接函数调用时。

其他人可能会发现可以为空的类型建议有用(虽然我想现在所有人都已经对这些建议进行了对比......)