不能为泛型类型创建的TypeConverter [英] Cannot create a TypeConverter for a generic type

查看:342
本文介绍了不能为泛型类型创建的TypeConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个的TypeConverter 的泛型类,如下所示:

I'd like to create a TypeConverter for a generic class, like this:

[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);
   }
}

问题出现在你不能有一个通用的在这条线上,它是不允许的:

The problem comes in that you cannot have a generic in this line, it is disallowed:

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

我的下一个方法是尝试定义,可以处理任何包装℃的单一的,非通用变频器; T&GT; 实例。反射和泛型的组合有我难倒就如何落实两个的ConvertTo ConvertFrom 方法。

My next approach was to try to define a single, non-generic Converter that could handle any Wrapper<T> instances. The mix of both reflection and generics has me stumped on how to implement both the ConvertTo and ConvertFrom methods.

因此​​,例如,我的ConvertTo看起来是这样的:

So for example, my ConvertTo looks like this:

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);
}

ConvertFrom 我最大的问题,因为我没有办法知道哪些包装类的进来的字符串转换成

In ConvertFrom I have the biggest problem because I have no way to know which Wrapper class to convert the incomming strings into.

我已经创建了几个custome类型和类型转换器用于与ASP.NET 4的Web API框架的使用,而这正是我需要这同样可以使用。

I've created several custome types and TypeConverters for use with the ASP.NET 4 Web API framework, and that is where I need this to be used as well.

我试过的另一件事是在运行时分配我对转换器通用版所看到的此处,但的WebAPI框架没有尊重它(意思是,从未创建的转换器)。

One other thing I tried was to assign my generic version of the Converter at runtime as seen here, but the WebAPI framework did not respect it (meaning, the converter was never created).

最后一点,我使用的.NET 4.0和VS 2010。

One last note, I'm using .NET 4.0 and VS 2010.

推荐答案

我通过创建一个单一的转换器,可以hanlde所有从我的泛型类derrived类型的解决了这个。知道ConvertFrom内通用ARG T的大问题
被捕获在构造函数中的信息,如下图所示解决。

I solved this by creating an single Converter that could hanlde all of the types derrived from my generic class. The big issue of knowing the generic arg T within the ConvertFrom was solved by capturing the information in the constructor as seen below.

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基础设施沉思调用此构造函数重载。这不是记录的类型转换器类的一部分。

It took me ages to discover that the .NET infrastructure reflectively calls this constructor overload if it is defined. It was not part of the documented TypeConverter class.

希望这一切都有助于未来的家伙。

Hope this all helps the next guy.

这篇关于不能为泛型类型创建的TypeConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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