Ody*_*dys 5 c# generics casting nullable .net-3.5
我正在创建一个通用的转换器
以下是通用转换器的示例代码
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;
}
Run Code Online (Sandbox Code Playgroud)
这就是我使用它的方式:
void foo()
{
DateTime? date = null;
TryReaderParse<DateTime?>("25/12/2012", out date);
}
Run Code Online (Sandbox Code Playgroud)
抛出的异常表示它无法转换DateTime为Nullable<DateTime>.既然,该方法创建并返回一个可空类型,那么转换怎么会失败呢?
最后,我希望在这个特定的例子中有一个可以为空的DateTime.
编辑问题是该StringToNullableDatetime方法返回一个Datetime?并且该转换表示无法转换Datetime
由于该StringToNullableDatetime方法返回一个可为空的日期时间,如何Convert.ChangeType才能看到传递的参数可以为空?
PS.我已经阅读过像这样的答案(从可空中铸造).
Eri*_*ert 18
抛出的异常表示它无法转换
DateTime为Nullable<DateTime>.既然,该方法创建并返回一个可空类型,那么转换怎么会失败呢?
好问题.这失败了,因为没有盒装可空的东西.当你转换DateTime?为object,你要么得到一个空引用,如果DateTime?是null,或者你得到盒装值,a DateTime.你永远不会得到一个盒装的可空结构; 哪有这回事.
因此,您最终会在该框中使用null或有效的DateTime.然后告诉Convert将其转换为可以为空的DateTime,并且Convert不知道如何做到这一点.
我的建议是你完全抛弃这一攻击线 ; 这段代码是泛滥的泛型.每当你切换特定类型的泛型时,你的代码就不再是通用的,你可能做错了.如果你想为日期时间做一个"尝试"式方法,那么只需写下:
DateTime? TryReadDateTime(object data)
{
... return null if the object cannot be read as a datetime ...
}
Run Code Online (Sandbox Code Playgroud)
为您打算阅读的每种类型编写这样的方法.用户更愿意写:
DateTime? d = TryReadDateTime(data);
if (d != null) ...
Run Code Online (Sandbox Code Playgroud)
比
DateTime d;
bool b = TryRead<DateTime>(data, out d);
if (b) ...
Run Code Online (Sandbox Code Playgroud)