質問

C#でConvert.ChangeTypeによる2つのライブラリクラス間の変換を実装したいと考えています。どちらのタイプも変更できません。たとえば、Guid と byte[] の間の変換です。

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

Guid が ToByteArray() メソッドを提供していることは知っていますが、Guid が byte[] に変換されるときにそれを呼び出すようにしたいと考えています。この背後にある理由は、変換が変更できないライブラリ コード (AseDataAdapter) でも行われるためです。それでは、2 つのクラスのいずれかのソースコードを変更せずに、2 つの型間の変換ルールを定義することは可能でしょうか。

TypeConverter を試していましたが、どちらも機能しないようです。

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

変数 tc は、byte[] への変換をサポートしない System.ComponentModel.GuidConverter に設定されます。同じクラスに 2 つの TypeConverter を使用できますか?たとえそれができたとしても、TypeConverter を割り当てるためにクラスのソース コードの先頭に属性を追加する必要はないでしょうか?

ありがとう

役に立ちましたか?

解決

登録した内容を変更することができます 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);
    }
}

他のヒント

System.ComponentModel.ICustomTypeDescriptor

はい、可能です。実行中のプログラムにそれを「挿入」するための関連情報については、MSDN のドキュメントを参照してください。(TypeDescriptor はメソッド IIRC を提供します)。

変換を実行しているコードがサポートしている場合 TypeConverter使用できます TypeConverterAttribute アセンブリレベルで。

残念ながら、それはできません。次のような拡張メソッドを作成できます。 現れる フレームワークの一部として 2 つのタイプ間の変換になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top