似乎TypeConverter.IsValid()
使用当前的线程区域性,但TypeConverter.ConvertFrom()
没有使用。
除非您处于不变文化中,否则这使得将TypeConverter.IsValid()
与DateTime
类型一起使用几乎没有用。确实,这似乎是一个错误。
有人知道如何使TypeConverter.IsValid()
使用当前的文化吗?
以下代码演示了该问题。
它使用两个字符串,一个为DD/MM/YYYY格式,一个为MM/DD/YYYY格式。
测试的第一部分是在不变文化中完成的。它表明TypeConverter.IsValid()
为MM/DD/YYYY字符串返回true,并且您可以使用TypeConverter.ConvertFrom()
将字符串转换为DateTime
。
第一部分还演示TypeConverter.IsValid()
为DD/MM/YYYY字符串返回false。
对于第二部分,我更改了使用“DD/MM/YYYY”日期的当前区域性“en-GB”。
现在,我希望IsValid()
结果可以颠倒,但是对于两个字符串,它返回的结果与以前相同。因此,它表示MM/DD/YYYY字符串有效。
但是-这是重要的一点-如果您尝试使用TypeConverter.ConvertFrom()
实际转换TypeConverter.IsValid()
认为还可以的字符串,则会出现异常。
有办法解决这个问题吗?
using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
namespace Demo
{
class Program
{
void Run()
{
// Start off with the US culture, which has MM/DD/YYYY date format.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var dateConverter = TypeDescriptor.GetConverter(typeof(DateTime));
var goodDateString = "07/19/1961";
var badDateString = "19/07/1961";
test(dateConverter, goodDateString, "DateTime"); // Says it's good.
test(dateConverter, badDateString, "DateTime"); // Says it's bad.
var dateTimeValue = (DateTime) dateConverter.ConvertFrom(goodDateString);
Console.WriteLine("dateTimeValue = " + dateTimeValue);
Console.WriteLine();
// Now lets change the current culture to the UK, which has DD/MM/YYYY date format.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
dateConverter = TypeDescriptor.GetConverter(typeof(DateTime));
test(dateConverter, goodDateString, "DateTime"); // Still says it's good.
test(dateConverter, badDateString, "DateTime"); // Still says it's bad.
// TypeConverter.IsValid(badDateString) returns false, so we shouldn't be able to convert it.
// Well, we can, like so:
dateTimeValue = (DateTime)dateConverter.ConvertFrom(badDateString); // Shouldn't work according to "IsValid()"
Console.WriteLine("dateTimeValue (bad) = " + dateTimeValue); // But this is printed ok.
// TypeConverter.IsValid(goodDateString) returns true, so we can convert it right?
// Well, no. This now throws an exception, even though "IsValid()" returned true for the same string.
dateTimeValue = (DateTime)dateConverter.ConvertFrom(goodDateString); // This throws an exception.
}
void test(TypeConverter converter, string text, string type)
{
if (converter.IsValid(text))
Console.WriteLine("\"" + text + "\" IS a valid " + type);
else
Console.WriteLine("\"" + text + "\" is NOT a valid " + type);
}
static void Main()
{
new Program().Run();
}
}
}
最佳答案
这是TypeConverter.IsValid()中的一个缺陷。类型转换器具有文化意识,其虚拟ConvertFrom()方法采用CultureInfo参数。您正在使用不占用CultureInfo的非虚拟重载,因此您将获得CultureInfo.CurrentCulture选择的转换。
TypeConverter.IsValid()没有接受CultureInfo的重载。然后将传递给TypeConverter.ConvertFrom()方法的CultureInfo进行欺骗,然后传递CultureInfo.InvariantCulture。
很难为此行为辩护。可能是一个刚发现为时已晚的漏洞,无法采取任何措施。当然,它不再是可修复的。
解决方法是通过指定正确的区域性来执行IsValid()的工作。首先调用CanConvertFrom(),然后在try/catch块中调用ConvertFrom()。
关于c# - TypeConverter.IsValid()使用当前的线程区域性,但TypeConverter.ConvertFrom()不?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16837774/