1

TypeConverters を使用してオブジェクトをジェネリック パラメーターとして指定された型に「キャスト」するサード パーティ コードを使用しています。

サードパーティのコードは文字列型コンバーターを取得し、それを介してすべての変換を行うことを期待しています。

var typeConverter = TypeDescriptor.GetConverter(typeof(string));

カスタム型とその型コンバーターを作成しました (そして TypeDescriptor 属性で登録しました) が、サード パーティのコードで使用されず、呼び出しで失敗します。typeConverter.CanConvertTo(MyCustomType)

今日まで、TypeConverters は抽象的な形でしか見たことがありませんでした。

ここで私が間違っていることを誰か知っていますか?

私の - 削減 - コード

using System;
using System.ComponentModel;

namespace IoNoddy
{
[TypeConverter(typeof(TypeConverterForMyCustomType))]
public class MyCustomType
{
    public Guid Guid { get; private set; }
    public MyCustomType(Guid guid)
    {
        Guid = guid;
    }
    public static MyCustomType Parse(string value)
    {
        return new MyCustomType(Guid.Parse(value));
    }
}

public class TypeConverterForMyCustomType
    : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
    }
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        string strValue;
        if ((strValue = value as string) != null)
            try
            {
                return MyCustomType.Parse(strValue);
            }
            catch (FormatException ex)
            {
                throw new FormatException(string.Format("ConvertInvalidPrimitive: Could not convert {0} to MyCustomType", value), ex);
            }
        return base.ConvertFrom(context, culture, value);
    }
}
}

static void Main(string[] args)
{
    // Analogous to what 3rd party code is doing: 
    var typeConverter = TypeDescriptor.GetConverter(typeof(string));
    // writes "Am I convertible? false"
    Console.WriteLine("Am I convertible? {0}",  typeConverter.CanConvertTo(typeof(MyCustomType))); 
}
4

1 に答える 1

4

CanConvertToをチェックして、コンバーターに追加します。

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return (destinationType == typeof(MyCustomType)) || base.CanConvertTo(context, destinationType);
    }

どこかに:

    public static void Register<T, TC>() where TC : TypeConverter
    {
        Attribute[] attr = new Attribute[1];
        TypeConverterAttribute vConv = new TypeConverterAttribute(typeof(TC));
        attr[0] = vConv;
        TypeDescriptor.AddAttributes(typeof(T), attr);
    }   

そしてメインに:

Register<string, TypeConverterForMyCustomType>();            
var typeConverter = TypeDescriptor.GetConverter(typeof(string));

その後、あなたのサンプルは動作します。

于 2013-02-21T17:11:57.673 に答える