I would like to implement conversion between two library classes by Convert.ChangeType in C#. I can change neither of the two types. For example converting between Guid and byte[].
Guid g = new Guid(); object o1 = g; byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception
I am aware that Guid provides a ToByteArray() method, but I would like to have that called when Guid is converted to byte[]. The reason behind this is that the conversion also takes place in library code (AseDataAdapter) which I can not modify. So is it possible to define a conversion rule between two types without modifying the sourcecode of either of the two classes?
I was experimenting with TypeConverter, but doesn't seem to work either:
Guid g = new Guid(); TypeConverter tc = TypeDescriptor.GetConverter(typeof(Guid)); byte[] b2 = (byte[])tc.ConvertTo(g, typeof(byte[])); // throws exception
The variable tc gets set to System.ComponentModel.GuidConverter which doesn't support conversions to byte[]. Can I have two TypeConverters for the same class? Even if I could, wouldn't I need to prepend an attribute to the source code of the class to assign a TypeConverter?
Thanks
Type conversion creates a value in a new type that is equivalent to the value of an old type, but does not necessarily preserve the identity (or exact value) of the original object. Conversion from a derived class to a base class. This means, for example, that an instance of any class or structure can be converted to an Object instance.
Initializes a new instance of the TypeConverter class. Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. Returns whether this converter can convert an object of the given type to the type of this converter.
The .NET Framework automatically supports the following conversions: Conversion from a derived class to a base class. This means, for example, that an instance of any class or structure can be converted to an Object instance. This conversion does not require a casting or conversion operator.
As you can see, it’s very easy to provide first-class support for dependency injection in .NET Core class libraries. The library itself can leverage dependency injection internally, as well as being available service-style to other libraries or applications that consume the library.
You can change the registered TypeConverter
for something using TypeDescriptor.AddAttributes
; this isn't quite the same as Convert.ChangeType
, but it may suffice:
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With