Кажется, что TypeConverter.IsValid()
использует текущую культуру темы, но TypeConverter.ConvertFrom()
нет.TypeConverter.IsValid() использует текущую культуру потока, но TypeConverter.ConvertFrom() нет?
Это делает бесполезным использование TypeConverter.IsValid()
с типом DateTime
, если вы не находитесь в культуре инвариантов. Действительно, это кажется ошибкой.
Кто-нибудь знает, как сделать TypeConverter.IsValid()
использовать текущую культуру?
Следующий код демонстрирует проблему.
Он использует две строки: одну в формате DD/MM/YYYY и одну в формате MM/DD/YYYY.
Первая часть теста проводится в Инвариантной культуре. Он демонстрирует, что TypeConverter.IsValid()
возвращает true для строки MM/DD/YYYY, и вы можете использовать TypeConverter.ConvertFrom()
для преобразования этой строки в DateTime
.
В первой части также показано, что TypeConverter.IsValid()
возвращает false для строки DD/MM/YYYY.
Для второй части я изменяю текущую культуру «en-GB», которая использует даты «DD/MM/YYYY».
Я бы ожидал, что результаты IsValid()
будут отменены, но они вернутся так же, как и раньше, для двух строк. Поэтому он говорит, что строка MM/DD/YYYY действительна.
Однако - и это важный бит - если вы попытаетесь использовать TypeConverter.ConvertFrom()
, чтобы фактически преобразовать строку, которую TypeConverter.IsValid()
сказал (а): ok, вы получите исключение.
Есть ли способ обойти это?
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();
}
}
}
Из памяти «нет» прыгает на ум. Но я, кажется, помню, что существует целый ряд проблем с API-интерфейсом IsValid, и во всех случаях он не очень хорошо работает. Может потребоваться просто попробовать конвертировать и посмотреть, работает ли он. –
@MarcGravell Aye, это похоже на подходящее действие - просто не используйте 'IsValid()' вообще. –