gpt4 book ai didi

c# - 无法为泛型类型创建 TypeConverter

转载 作者:可可西里 更新时间:2023-11-01 08:00:53 25 4
gpt4 key购买 nike

我想创建一个 TypeConverter对于通用类,像这样:

[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> 的单个非通用 Converter实例。反射和泛型的混合让我对如何实现两者 ConvertTo感到困惑。和 ConvertFrom方法。

例如,我的 ConvertTo 看起来像这样:

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我遇到了最大的问题,因为我无法知道将传入的字符串转换成哪个 Wrapper 类。

我已经创建了几个客户类型和 TypeConverters 用于 ASP.NET 4 Web API 框架,这也是我需要使用它的地方。

我尝试的另一件事是在运行时分配转换器的通用版本,如 here 所示,但 WebAPI 框架不尊重它(意思是,从未创建转换器)。

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

最佳答案

我通过创建一个可以处理从我的泛型类派生的所有类型的单个转换器来解决这个问题。了解 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 类的一部分。

希望这一切对下一个人有所帮助。

关于c# - 无法为泛型类型创建 TypeConverter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14823669/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com