我正在创建一个通用转换器
这是通用转换器的示例代码
bool TryReaderParse<TType>(object data, out TType value)
{
value = default(TType);
Type returnType = typeof(TType);
object tmpValue = null;
if (returnType == typeof(DateTime))
{
tmpValue = StringToDatetime(data.ToString());
}
else if (returnType == typeof(DateTime?)) // THIS IF FIRES
{
tmpValue = StringToNullableDatetime(data.ToString());
}
value = (TType)Convert.ChangeType(tmpValue, returnType); // THROWS
}
public DateTime? StringToNullableDatetime(string date)
{
DateTime? datetime = null;
if (!string.IsNullOrEmpty(date))
{
datetime = DateTime.Parse(date, new CultureInfo(Resources.CurrentCulture));
}
return datetime;
}
这就是我使用它的方式:
void foo()
{
DateTime? date = null;
TryReaderParse<DateTime?>("25/12/2012", out date);
}
抛出的异常表示它无法从 DateTime
转换至 Nullable<DateTime>
.既然该方法创建并返回一个可为 null 的类型,为什么转换会失败?
最后,在这个特定示例中,我想要一个可为 null 的 DateTime。
编辑 问题是StringToNullableDatetime
方法返回 Datetime?
并且类型转换示无法从 Datetime
转换
自 StringToNullableDatetime
方法返回一个可为空的日期时间,Convert.ChangeType
怎么可能看不到传递的参数可以为空?
附言。我读过类似 this 的答案一个做相反的事情(从可空转换)。
最佳答案
The thrown exception says that it cannot convert from
DateTime
toNullable<DateTime>
. Since, the method creates and returns a nullable type, how come the casting fails?
好问题。这失败了,因为不存在盒装可为 nullable 之类的东西。当您转换 DateTime?
至 object
,你要么得到一个空引用,如果 DateTime?
为空,或者您得到盒装的值,一个DateTime
.你永远不会得到一个装箱的可为空的结构;没有这样的事情。
因此,您最终会在该框中得到 null 或有效的 DateTime。然后,您告诉 Convert 将其转换为可为 null 的 DateTime,而 Convert 不知道如何执行此操作。
我的建议是您完全放弃这种攻击方式;这段代码滥用了泛型。任何时候您在泛型的特定类型上进行切换,您的代码都不再是泛型,并且您可能做错了。如果你想为日期时间做一个“try”式的方法,那么就这样写:
DateTime? TryReadDateTime(object data)
{
... return null if the object cannot be read as a datetime ...
}
为您打算阅读的每种 类型编写这样的方法。用户更愿意写:
DateTime? d = TryReadDateTime(data);
if (d != null) ...
比
DateTime d;
bool b = TryRead<DateTime>(data, out d);
if (b) ...
关于c# - 无法在泛型方法中将类型更改为可为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10318334/