找不到属性

时间:2017-09-20 19:51:40

标签: c# linqpad typeconverter

这基本上是问题的延续:Typeconverter not working for single properties

最初的问题没有得到回答,但它似乎是我项目中特定场景的前进方向,特别是因为我所有的阅读都表明它应该真的有效。我给了它一个镜头,但提出了与最终评论中提到的相同的问题(没有断点被击中,或者在我的情况下,没有输出被转储到结果窗口)。这就是我的开始,根据我的需要进行了一个基本的例子†。

在LINQPad中

void Main()
{
    var prop = typeof(Request).GetProperty("Names");
    var converter = TypeDescriptor.GetConverter(prop.PropertyType.Dump()).Dump();
    var value = converter.ConvertFrom("One,Two").Dump();
}

public class Request
{
    [TypeConverter(typeof(EnumerableTypeConverter<string>))]
    public IEnumerable<string> Names { get; set; }
}

public class EnumerableTypeConverter<T> : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        new { Context = context, SourceType = sourceType }.Dump("CanConvertFrom");

        if (sourceType == typeof(string))
            return true;

        return false;
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        new { Context = context, DestinationType = destinationType }.Dump("CanConvertTo");

        return true;
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        new { Context = context, Culture = culture, Value = value }.Dump("ConvertFrom");

        var source = value as string;

        if (source == null)
            return value.ToString();

        return source;
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        new { Context = context, Culture = culture, Value = value, DestinationType = destinationType }.Dump("ConvertTo");

        var s = value as IEnumerable<string>;

        return s != null ? string.Join(",", s) : base.ConvertFrom(context, culture, value);
    }

    public override bool IsValid(ITypeDescriptorContext context, object value)
    {
        new { Context = context, Value = value }.Dump("IsValid");

        return true;
    }
}

输出

typeof(IEnumerable<String>)
System.Collections.Generic.IEnumerable`1[System.String]

ReferenceConverter
System.ComponentModel.ReferenceConverter

null

这表明问题是以下问题之一:1)它没有看到TypeConverterAttribute定义,2)它没有找到我的自定义TypeConverter,或者3)它无法创建它默默地失败了。所有这些似乎都不太可能,但显然结果不是谎言。因此,我理解的东西是不对的。当我直接实例化一个实例时,我没有遇到任何异常。

var testConverter = new EnumerableTypeConverter<string>().Dump();

EnumerableTypeConverter<String>
UserQuery+EnumerableTypeConverter`1[System.String]

对于笑嘻嘻和笑声,我尝试了非通用的方法

[TypeConverter(typeof(EnumerableStringConverter))]
public IEnumerable<string> Names { get; set; }

public class EnumerableStringConverter : TypeConverter
{
    // -- same implementation as EnumerableTypeConverter<T> --
}

但收到了同样的结果。我在这里缺少什么?

†代码将读取包含属性名称和关联值的文件。接下来,它将按名称查找匹配属性,并通过转换器设置值。一些真正的值是JSON数组,但在创建将反序列化的JSON数组返回到匹配属性的完整解决方案之前,我正在采取一些小步骤来验证我在做什么。

1 个答案:

答案 0 :(得分:2)

您将转换器设置为属性,因此您应该为此属性获取转换器而不是类型IEnumerable<string>

static void Main(string[] args)
{
    var properties = TypeDescriptor.GetProperties(typeof(Request));
    var propItem = properties["Names"];
    var converter = propItem.Converter;
    // converter has type {EnumerableTypeConverter<string>}
}