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

在C#2.0中使用Invoke调用时,参数从null转换为DateTime.MinValue,c#,reflection,C#,Reflection,我的代码有点像这样 public class MyObject { private bool IsValidDay(ref DateTime theDate) { ... } } MethodInfo[] methods = myObjectInstance.GetType().GetMethod("IsValidDay", BindingFlags.Instance | BindingFlags.NonPublic); object[] args = {

我的代码有点像这样

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方法中调用该方法时,日期是DateTime.MinValue。这看起来非常奇怪-我可能希望抛出一个NullReferenceException,但不是一个自动转换

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

对于随后调用的其他代码而言,DateTime.MinValue和null不是一回事,所以这是一个小问题


有什么线索吗??建议。

日期时间变量不能为空。它不是引用类型,因此不会出现空引用异常

你可以做:

private bool IsValidDay(ref DateTime? theDate)
{
   if(theDate.HasValue)...
}
这里有一个关于可空类型的链接:


我想我明白你的要求了。。。。对于您的代码(特别是由于ref参数,您不能在参数上与ref或out有差异)。它必须传入一个DateTime对象。它不可能是其他任何东西……因此必须将null参数转换为某种东西才能使函数工作

DateTime
有一个值,我建议您使用
DateTime?
(或
Nullable
)来支持null

只能为null。(如int、bool、structs和enums)是一个。因此DateTime不能为null,就像枚举不能为null一样。通过将其声明为
DateTime?
,可以使用。这将允许您检查它是否为空。

来自:

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

DateTime
的默认值是
DateTime.MinValue

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

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

请注意,在无反射调用方法时,无论如何都不能将
null
传递给该方法:

DateTime dt = null; // cannot assign null to value type
obj.IsValidDay(ref dt);
所以我想说,您不需要使用空引用来测试您的方法。


如果希望方法接受
null
,可以将声明更改为
DateTime?
,其他人已经指出:

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

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

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

这是MSDN库中调用方法文档的注释:

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

还发现了本教程:

最后,在这种情况下,我想我会同意这样一种观点,即该方法实际上不需要对null进行测试,并提醒自己,当直接调用函数时,通过反射调用方法并不总是抛出异常


其他人可能会发现nullable类型的建议很有用(尽管我想现在每个人都对这些建议有所了解……)

我知道可为null的类型,过去也使用过它们,并且同意它们可能是这项工作的工具-不幸的是,我正在维护/扩展无法更改为可为null的类型的现有代码。据我所知,传递ref参数以调用的唯一方法与我在示例代码中所做的相同,这是我从MSDN en中获得的试试ref参数。是的,看来我不明白Invoke()正确使用ref参数调用。修复我的响应…有关可为null的类型建议,请参阅上面的注释。在调用单元测试代码中,该值被显式初始化为null-但它的作用与您上面描述的一样。我必须检查实际的生产代码-我认为可以通过反射调用该方法,但我我不确定-hill必须深入研究我们的框架代码,以确保它不存在。那么,您希望它做什么?