我正在使用4.0,并试图通过开发一些类型转换的助手方法来简化我的生活。下面的方法工作得很好。它将从任何字符串转换为其他数据类型。
System.ComponentModel;
public static T Convert<T>(string s)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return (T)typeConverter.ConvertFrom(s);
}
return default(T);
}
//calling this method...
var dateTime = MyConverter.Convert<DateTime>("13/07/2013"); // Date format "DD/mm/yyyy"
// Working as expected... Taking "13" as Day, "07" as month现在,以下方法也在同一个类MyConverter中,但它不能很好地使用DateTime:
public static bool CanConvertTo<T>(string s)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return typeConverter.IsValid(s);
}
else
return false;
}这个方法的问题是,它只接受日期格式:"MM/dd/yyyy“
// This will give exception. It is taking "13" as month, "07" as Day
bool canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013");按照编辑的建议,我将方法更改为:
public static bool CanConvertTo<T>(string s)
{
TypeConverter typeConverter;
if (typeof(T) == typeof(DateTime))
{
typeConverter = new DateTimeConverter();
}
else
{
typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return typeConverter.IsValid(s);
}
else
return false;
}并进行了测试。测试结果如下:
var date = MyConverter.Convert<DateTime>("13/07/2013"); //return perfect date
var canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013"); // returned false...所以DateTimeConverter没有成功
发布于 2013-07-04 10:42:53
由于DateTime可以有许多不同的格式样式,所以我只使用DateTimeConverter,而不是尝试在泛型方法中重新创建它。
编辑
我做了一些ILspying,这就是我得出的结论(很高兴在任何一点上都能得到纠正)。
GetCoverter(typeof(DateTime))将返回一个DateTimeConverter,因此调用CanConvertFrom实际上是在调用DateTimeConverter.CanConvertFrom。CanConvertFrom调用base.CanConvertFrom (base是父TypeConverter类)。
base.CanConvertFrom方法如下所示
public virtual bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(InstanceDescriptor);
}因为DateTime.GetType() != typeof(InstanceDescriptor),返回值是false。CanConvertFrom由IsValid方法调用,因为我们刚刚建立了返回值为false,IsValid返回false。
那么,Convert方法是如何工作的,即使调用了相同的CanConvertFrom方法?
您要传递的参数是string类型,而不是DateTime类型。
typeConverter.CanConvertFrom(typeof(string))在上面的第一个代码片段中,CanConvertFrom方法用于TypeConverter基类。如果我们看一下DateTimeConverter.CanConvertFrom覆盖,它看起来就像这样
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}因为我们作为类型传入一个String,所以这个方法返回true (与IsValid调用不同)。因为这返回true,所以代码继续调用
return (T)typeConverter.ConvertFrom(s);(其中T是DateTime)
DateTimeConverter简单地调用DateTime.Parse并忽略区域性。我不确定这是由设计还是错误造成的,但是我不会依赖DateTime.Parse,除非您知道字符串总是相同的格式(或者在调用方法之前正确地格式化它)。
发布于 2017-12-01 14:01:08
DateTimeConverter.IsValid不使用当前的文化。我是怎么绕过这件事的
public class FixedDateTimeConverter : DateTimeConverter
{
public override bool IsValid(ITypeDescriptorContext context, object value)
{
DateTime d;
return DateTime.TryParse(value.ToString(), out d);
}
}..。
var converter = TypeDescriptor.GetConverter(typeof (T));
if (typeof (T) == typeof (DateTime))
converter = new FixedDateTimeConverter();
return converter.IsValid(null,r);https://stackoverflow.com/questions/17468111
复制相似问题