10

ジェネリック型のためにTypeConverterを作成できません:あなたはこのラインでジェネリックを使用することはできませんが、私はこのように、一般的なクラスの<code>TypeConverter</code>を作成したいと思います

[TypeConverter(typeof(WrapperConverter<T>))] 
public class Wrapper<T> 
{ 

    public T Value 
    { 
     // get & set 
    } 

    // other methods 

} 


public class WrapperConverter<T> : TypeConverter<T> 
{ 

    // only support To and From strings 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     if (sourceType == typeof(string)) 
     { 
     return true; 
     } 
     return base.CanConvertFrom(context, sourceType); 
    } 

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 
    { 
     if (destinationType == typeof(string)) 
     { 
     return true; 
     } 
     return base.CanConvertTo(context, destinationType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 
    { 
     if (value is string)   
     { 
     TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); 
     T inner = converter.ConvertTo(value, destinationType); 
     return new Wrapper<T>(inner); 
     } 
     return base.ConvertFrom(context, culture, value); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) 
    { 
     if (destinationType == typeof(System.String)) 
     { 
     Wrapper<T> wrapper = value as Wrapper<T>(); 
     TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); 
     return converter.ConvertTo(wrapper.Value, destinationType); 
     } 
     return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

問題はそれに来る、それがあります禁止:

[TypeConverter(typeof(WrapperConverter<T>))] 
public class Wrapper<T> 

私の次のアプローチは、任意のWrapper<T>のインスタンスを扱うことができ、単一の、非ジェネリックコンバータを定義しようとしました。反射とジェネリックの両方の組み合わせは、ConvertToConvertFromの両方の方法をどのように実装するのかについて私は困惑しています。私はにincomming文字列を変換するために、どのラッパークラス知る方法がないので、私は最大の問題を持っているConvertFrom

public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) 
{ 
    if (destinationType == typeof(System.String)   
     && value.GetType().IsGenericType) 
    { 

     // 1. How do I enforce that value is a Wrapper<T> instance? 

     Type innerType = value.GetType().GetGenericArguments()[0]; 

     TypeConverter converter = TypeDescriptor.GetConverter(innerType); 

     // 2. How do I get to the T Value property? Introduce an interface that Wrapper<T> implements maybe? 
     object innerValue = ??? 

     return converter.ConvertTo(innerValue, destinationType); 


    } 
    return base.ConvertTo(context, culture, value, destinationType); 
} 

だから例えば、私をConvertToは次のようになります。

私は、ASP.NET 4 Web APIフレームワークで使用するいくつかのカスタム型とTypeConvertersを作成しました。ここでは、これを使用する必要があります。

私が試したもう1つの事は、hereと表示されているように、私の汎用バージョンのコンバータを実行時に割り当てることでしたが、WebAPIフレームワークはそれを尊重しませんでした。

一つの最後のノート、私は.NET 4.0とVS 2010

+0

私は以前にこの問題を解決しました。私はT型をキャストするためにダイナミックを使用し、typeofも使用したと信じています。明日私のソリューションを投稿することができるはずです。私はこの時点でコードにアクセスできません。 – awright18

+0

http://stackoverflow.com/questions/557340/c-sharp-generic-list-t-how-to-get-the-type-of-tこれが役に立ちますか? – awright18

+0

@ awright18ありがとうございましたが、私は必要なものを持っていませんでした。私の質問は、ジェネリック型のためにTypeConverterを作成して関連付ける方法です。 – tcarvin

答えて

28

を使用しています私は私のジェネリッククラスからderrivedタイプをすべてhanldeことができ、単一のコンバータを作成することによって、これを解決しました。 ConvertFrom 内のジェネリックarg Tを知ることの大きな問題は、以下に示すようにコンストラクタの情報をキャプチャすることによって解決されました。

public MyGenericConverter(Type type) 
{ 
    if (type.IsGenericType 
     && type.GetGenericTypeDefinition() == typeof(MyGenericClass<>) 
     && type.GetGenericArguments().Length == 1) 
    { 
     _genericInstanceType = type; 
     _innerType = type.GetGenericArguments()[0]; 
     _innerTypeConverter = TypeDescriptor.GetConverter(_innerType);    
    } 
    else 
    { 
     throw new ArgumentException("Incompatible type", "type"); 
    } 
} 

.NETインフラストラクチャは、定義されている場合、このコンストラクタのオーバーロードを反映していることがわかりました。これは、文書化されたTypeConverterクラスの一部ではありませんでした。

このすべてが次の男に役立つことを願っています。

+3

ニース!先端に感謝します。最終的に目標タイプを知ることができないと思ったところで私の問題を解決しました。文書化されていないとおそらく、将来の破損の可能性があります。 –

+0

これ以上動作しないようですか? (.NET 4.5) –

+0

ええと、私は見てみましょう。そのプロジェクトはまだ4.0になっているので、そのバージョンでのみ動作するかどうかは確認できません。 – tcarvin

関連する問題