2009-03-03 132 views
21

我想通过C#中的Convert.ChangeType实现两个库类之间的转换。我可以改变这两种类型。例如在Guid和byte []之间转换。我知道Guid提供了一个ToByteArray()方法,但我希望在Guid被转换为byte []时调用该方法。这背后的原因是转换也发生在我无法修改的库代码(AseDataAdapter)中。那么是否可以在两种类型之间定义转换规则而不修改两个类中的任何一个的源代码?将自定义类型转换为.NET库类

我用的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?

感谢

回答

36

您可以使用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); 
    } 
} 
-2

不幸的是,不,你不能 - 你可以写,将出现是作为框架的一部分,两种类型之间转换的扩展方法。

0

如果执行转换的代码支持TypeConverter,您可以在程序集级别使用TypeConverterAttribute

+0

据我所知,有TypeConverterAttribute没有装配级使用;你可以做每个类型和每个属性,并通过TypeDescriptor重写 - 但没有集合级别?我错过了什么吗? – 2009-03-03 16:06:19

+0

TypeConverterAttribute被声明为AttributeTargets.All ...和ISTR看到这在WF中使用。 – Richard 2009-03-04 08:57:34

0
System.ComponentModel.ICustomTypeDescriptor 

是的,这是可能的。请阅读MSDN上的文档以获取相关信息,将其“注入”到正在运行的程序中。 (TypeDescriptor提供了IIRC方法)。

+0

这是大量的矫枉过正......要么在个别属性(由PropertyDescriptor尊重)上使用[TypeConverter],要么使用我的文章中显示的全局方法。 – 2009-03-03 16:04:29

相关问题