Pergunta

Eu gostaria de implementar a conversão entre duas classes de biblioteca por Convert.ChangeType em C #. Eu posso mudar nenhum dos dois tipos. Por exemplo a conversão entre GUID e byte [].

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

Estou ciente de que Guid fornece um método ToByteArray (), mas eu gostaria de ter esse chamado quando Guid é convertida para byte []. A razão por trás disso é que a conversão também ocorre no código da biblioteca (AseDataAdapter) que eu não posso modificar. Assim, é possível definir uma regra de conversão entre dois tipos sem modificar o código fonte de qualquer das duas classes?

Eu estava experimentando com TypeConverter, mas não parece que quer trabalhar:

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

O tc variável é configurado para System.ComponentModel.GuidConverter que não suporta conversões para byte []. Posso ter dois TypeConverters para a mesma classe? Mesmo que pudesse, não seria eu preciso para preceder um atributo ao código-fonte da classe para atribuir um TypeConverter?

Graças

Foi útil?

Solução

Você pode alterar a TypeConverter registrado para algo usando TypeDescriptor.AddAttributes; isso não é exatamente o mesmo que Convert.ChangeType, mas pode 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);
    }
}

Outras dicas

System.ComponentModel.ICustomTypeDescriptor

Sim, é possível. Leia a documentação no MSDN para obter informações relacionadas a 'injetar' que para o programa em execução. (TypeDescriptor fornece o método IIRC).

Se o código que está executando as TypeConverters suporta a conversão você pode usar TypeConverterAttribute em um nível de montagem.

Infelizmente não você não pode -. Você poderia escrever um método de extensão que aparecer ser uma conversão entre dois tipos como parte do quadro

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top