TypeConverter.IsValid() 使用当前线程文化,但 TypeConverter.ConvertFrom() 不使用? [英] TypeConverter.IsValid() uses current thread culture but TypeConverter.ConvertFrom() doesn't?

查看:20
本文介绍了TypeConverter.IsValid() 使用当前线程文化,但 TypeConverter.ConvertFrom() 不使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎 TypeConverter.IsValid() 使用当前的线程文化,但 TypeConverter.ConvertFrom() 没有.

It seems that TypeConverter.IsValid() uses the current thread culture but TypeConverter.ConvertFrom() doesn't.

这使得将 TypeConverter.IsValid()DateTime 类型一起使用变得非常无用,除非您处于不变文化中.确实,这似乎是一个错误.

This makes it pretty useless to use TypeConverter.IsValid() with the DateTime type unless you are in the invariant culture. Indeed, it seems to be a bug.

有谁知道如何让 TypeConverter.IsValid() 使用当前的文化?

Does anyone know how to make TypeConverter.IsValid() use the current culture?

下面的代码演示了这个问题.

The following code demonstrates the problem.

它使用两个字符串,一个是 DD/MM/YYYY 格式,一个是 MM/DD/YYYY 格式.

It uses two strings, one in DD/MM/YYYY format and one in MM/DD/YYYY format.

测试的第一部分是在不变文化中完成的.它表明 TypeConverter.IsValid() 为 MM/DD/YYYY 字符串返回 true,并且您可以使用 TypeConverter.ConvertFrom() 将该字符串转换为 日期时间.

The first part of the test is done in the Invariant Culture. It demonstrates that TypeConverter.IsValid() returns true for the MM/DD/YYYY string and that you can use TypeConverter.ConvertFrom() to convert that string to a DateTime.

第一部分还演示了 TypeConverter.IsValid() 为 DD/MM/YYYY 字符串返回 false.

The first part also demonstrates that TypeConverter.IsValid() returns false for the DD/MM/YYYY string.

对于第二部分,我更改了使用DD/MM/YYYY"日期的当前区域性en-GB".

For the second part, I change the current culture "en-GB" which uses "DD/MM/YYYY" dates.

我现在希望 IsValid() 结果被反转,但它返回与之前相同的两个字符串.所以它说 MM/DD/YYYY 字符串是有效的.

I would now expect the IsValid() results to be reversed, but it returns the same as before for the two strings. So it says that the MM/DD/YYYY string is valid.

但是 - 这是重要的一点 - 如果您尝试使用 TypeConverter.ConvertFrom() 来实际转换 TypeConverter.IsValid() 说没问题的字符串,你会得到一个例外.

However - and this is the important bit - if you try to use TypeConverter.ConvertFrom() to actually convert the string which TypeConverter.IsValid() said was ok, you will get an exception.

有没有办法解决这个问题?

Is there a way to work around this?

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 选择的转换.

It is a flaw in TypeConverter.IsValid(). A type converter is culture-aware, its virtual ConvertFrom() method takes a CultureInfo argument. You are using the non-virtual overload that doesn't take a CultureInfo so you'll get the conversion selected by CultureInfo.CurrentCulture.

TypeConverter.IsValid() 确实没有具有接受 CultureInfo 的重载.并清除它传递给 TypeConverter.ConvertFrom() 方法的 CultureInfo,它传递 CultureInfo.InvariantCulture.

TypeConverter.IsValid() does not have an overload that accepts a CultureInfo. And flubs the CultureInfo it passes to the TypeConverter.ConvertFrom() method, it passes CultureInfo.InvariantCulture.

很难为这种行为找到理由.可能是一个刚刚被发现太晚而无法做任何事情的错误.它肯定无法再修复了.

Hard to come up with a justification for this behavior. Probably a bug that just got noticed too late to do anything about. It certainly isn't fixable anymore.

解决方法是执行 IsValid() 所做的操作,但要指定正确的区域性.首先调用 CanConvertFrom(),然后在 try/catch 块中调用 ConvertFrom().

The workaround is to do what IsValid() does but by specifying the correct culture. First call CanConvertFrom(), then call ConvertFrom() in a try/catch block.

这篇关于TypeConverter.IsValid() 使用当前线程文化,但 TypeConverter.ConvertFrom() 不使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆