27

我想通过 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[]。我可以为同一个班级有两个 TypeConverter 吗?即使可以,我是否不需要在类的源代码中添加一个属性来分配 TypeConverter?

谢谢

4

4 回答 4

51

TypeConverter您可以使用TypeDescriptor.AddAttributes;更改已注册的内容 这与 不太一样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);
    }
}
于 2009-03-03T16:03:26.983 回答
0

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

于 2009-03-03T15:43:31.443 回答
-1
System.ComponentModel.ICustomTypeDescriptor

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

于 2009-03-03T15:59:09.333 回答
-2

不幸的是,你不能——你可以编写一个扩展方法,作为框架的一部分,它似乎是两种类型之间的转换。

于 2009-03-03T15:36:29.590 回答