online - system.guid c# example
Inyectar conversión de tipo personalizado a clases de biblioteca.NET (4)
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
Desafortunadamente, no puedes, puedes escribir un método de extensión que parezca ser una conversión entre dos tipos como parte del marco.
Puede cambiar el TypeConverter
registrado para algo usando TypeDescriptor.AddAttributes
; esto no es exactamente 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);
}
}
Si el código que realiza la conversión es compatible con TypeConverter
s, puede utilizar TypeConverterAttribute
en un nivel de ensamblaje.
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).