Pregunta

Me gustaría implementar la conversión entre dos clases de biblioteca mediante Convert.ChangeType en C #. No puedo cambiar ninguno de los dos tipos. Por ejemplo, la conversión entre Guid y byte [].

Guid g = new Guid();
object o1 = g;
byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception

Soy consciente de que Guid proporciona un método ToByteArray (), pero me gustaría que se llame cuando Guid se convierte a byte []. La razón detrás de esto es que la conversión también tiene lugar en el código de la biblioteca (AseDataAdapter) que no puedo modificar. Entonces, ¿es posible definir una regla de conversión entre dos tipos sin modificar el código fuente de cualquiera de las dos clases?

Estaba experimentando con TypeConverter, pero parece que tampoco funciona:

Guid g = new Guid();
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Guid));
byte[] b2 = (byte[])tc.ConvertTo(g, typeof(byte[])); // throws exception

La variable tc se establece en System.ComponentModel.GuidConverter que no admite conversiones a byte []. ¿Puedo tener dos TypeConverters para la misma clase? Incluso si pudiera, ¿no tendría que anteponer un atributo al código fuente de la clase para asignar un TypeConverter?

Gracias

¿Fue útil?

Solución

Puedes cambiar el TypeConverter registrado para algo usando TypeDescriptor.AddAttributes ; esto no es lo mismo que Convert.ChangeType , pero puede ser suficiente:

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);
    }
}

Otros consejos

System.ComponentModel.ICustomTypeDescriptor

Sí, es posible. Lea la documentación en MSDN para obtener información relacionada para 'inyectar' eso en el programa en ejecución. (TypeDescriptor proporciona el método IIRC).

Si el código que está realizando la conversión es compatible con TypeConverter s puede usar TypeConverterAttribute a nivel de ensamblaje.

Desafortunadamente, no puedes, puedes escribir un método de extensión que aparezca para que sea una conversión entre dos tipos como parte del marco.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top