4

私は 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;
}

このメソッドの問題は、dateformat のみを受け入れることです: "MM/dd/yyyy"

// This will give exception. It is taking "13" as month, "07" as Day
bool canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013");

編集 KeyboardP の提案に従って、方法を次のように変更しました。

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

4

2 に答える 2

3

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あることを確立したばかりなので、 を返します。falseIsValidfalse

では、同じメソッドが呼び出され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);
}

タイプとしてa を渡しているためString、このメソッドは true を返します (IsValid呼び出しとは異なります)。これは true を返すため、コードは引き続き呼び出します

return (T)typeConverter.ConvertFrom(s);

(ここで、T はDateTime)

DateTimeConverter単にDateTime.Parse文化を呼び出して無視します。これが仕様によるものかバグによるものかはDateTime.Parseわかりませんが、文字列が常に同じ形式であることがわかっている場合 (または、メソッドを呼び出す前に正しく書式設定している場合) を除き、私は依存しません。

于 2013-07-04T10:42:53.723 に答える