C# 将自定义类型转换注入.NET库类

C# 将自定义类型转换注入.NET库类,c#,.net,guid,C#,.net,Guid,我想通过C#中的Convert.ChangeType实现两个库类之间的转换。这两种类型我都不能改变。例如,在Guid和字节[]之间转换 Guid g = new Guid(); object o1 = g; byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception 我知道Guid提供了ToByteArray()方法,但我希望在将Guid转换为字节[]时调用该方法。这背后的原因是转换也发生在我无

我想通过C#中的Convert.ChangeType实现两个库类之间的转换。这两种类型我都不能改变。例如,在Guid和字节[]之间转换

Guid g = new Guid();
object o1 = g;
byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception
我知道Guid提供了ToByteArray()方法,但我希望在将Guid转换为字节[]时调用该方法。这背后的原因是转换也发生在我无法修改的库代码(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,该变量不支持转换为字节[]。我能为同一个班级要两台打字机吗?即使可以,我是否需要为类的源代码预先添加一个属性来分配一个TypeConverter


谢谢

不幸的是,您不能-您可以编写一个扩展方法,作为框架的一部分在两种类型之间进行转换。

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

System.ComponentModel.ICustomTypeDescriptor

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

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

这真是太过分了。。。要么在单个属性上使用[TypeConverter](PropertyDescriptor尊重),要么使用my post.AFAIK中显示的全局方法,TypeConverterAttribute在程序集级别没有使用;您可以按类型和按属性进行操作,并通过TypeDescriptor进行重写,但没有程序集级别?我错过什么了吗?TypeConverterAttribute声明为AttributeTargets。所有。。。ISTR在WF.+1中看到这一点时,甚至没有意识到可以通过TypeDescriptor.AddAttributes添加属性——这可能非常有用。请注意,它们不是真实的属性——反射不会看到它们;仅System.ComponentModelMarc,您能否详细说明如何使用自定义的
TypeDescriptorProvider
并重载
GetTypeDescriptor
->
GetConverter
链?使用
TypeDescriptor.AddProvider
进行实际注册时,它似乎会产生相同的结果,而且稍微干净一些,尽管它当然要更详细一些,因为您需要同时创建
TypeDescriptorProvider
ICustomTypeDescriptor
。以这种方式注册它会完全覆盖该对象的标准
TypeDescriptor
,还是与现有注册一致?