2009-03-03 122 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

相關問題