题
我想通过C#中的Convert.ChangeType实现两个库类之间的转换。我可以改变这两种类型。例如,在Guid和byte []之间进行转换。
Guid g = new Guid();
object o1 = g;
byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception
我知道Guid提供了一个ToByteArray()方法,但我希望在Guid转换为byte []时调用它。这背后的原因是转换也发生在我无法修改的库代码(AseDataAdapter)中。那么是否可以在两种类型之间定义转换规则而无需修改两个类中任何一个的源代码?
我正在尝试使用TypeConverter,但似乎也不起作用:
Guid g = new Guid();
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Guid));
byte[] b2 = (byte[])tc.ConvertTo(g, typeof(byte[])); // throws exception
变量tc设置为System.ComponentModel.GuidConverter,它不支持转换为byte []。我可以为同一个班级安排两个TypeConverters吗?即使我可以,我不需要在类的源代码前添加属性来分配TypeConverter吗?
由于
解决方案
您可以使用 TypeDescriptor.AddAttributes
更改已注册的 TypeConverter
。这与 Convert.ChangeType
不完全相同,但它可能就足够了:
using System;
using System.ComponentModel;
static class Program
{
static void Main()
{
TypeDescriptor.AddAttributes(typeof(Guid), new TypeConverterAttribute(
typeof(MyGuidConverter)));
Guid guid = Guid.NewGuid();
TypeConverter conv = TypeDescriptor.GetConverter(guid);
byte[] data = (byte[])conv.ConvertTo(guid, typeof(byte[]));
Guid newGuid = (Guid)conv.ConvertFrom(data);
}
}
class MyGuidConverter : GuidConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(byte[]) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(byte[]) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value != null && value is byte[])
{
return new Guid((byte[])value);
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(byte[]))
{
return ((Guid)value).ToByteArray();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
其他提示
System.ComponentModel.ICustomTypeDescriptor
是的,有可能。阅读MSDN上的文档以获取相关信息,以便将其“注入”正在运行的程序中。 (TypeDescriptor提供方法IIRC)。
如果执行转换的代码支持 TypeConverter
,则可以在汇编级别使用 TypeConverterAttribute
。
不幸的是,你不能 - 你可以编写一个出现的扩展方法,作为框架的一部分,在两种类型之间进行转换。
不隶属于 StackOverflow