【问题标题】:Convert string to Array of string using TypeConverter使用 TypeConverter 将字符串转换为字符串数组
【发布时间】:2016-03-23 15:38:15
【问题描述】:

我需要将字符串"foo1,foo2,foo3" 转换为string[]

我想使用TypeConverter 或其子ArrayConverter。它包含方法ConvertFromString

但是如果我调用这个方法,我会捕获一个异常ArrayConverter cannot convert from System.String.

我知道Split,不要向我推荐这个解决方案。

----解决方案---

使用@Marc Gravell 的建议和@Patrick Hofman 对此主题的回答我写了CustumTypeDescriptorProvider

public class CustumTypeDescriptorProvider:TypeDescriptionProvider
    {
        public override ICustomTypeDescriptor GetTypeDescriptor(System.Type objectType, object instance)
        {
            if (objectType.Name == "String[]") return new StringArrayDescriptor();
            return base.GetTypeDescriptor(objectType, instance);
        }
    }
public class StringArrayDescriptor : CustomTypeDescriptor
    {
        public override TypeConverter GetConverter()
        {
            return new StringArrayConverter();
        }
    }

StringArrayConverter 在此帖子下方的答案中实现。 为了使用它,我将CustumTypeDescriptorProvider 添加到提供者集合中

 TypeDescriptor.AddProvider(new CustumTypeDescriptorProvider(), typeof(string[]));

要在TestClass 中使用它,您需要编写几行代码:

 TypeConverter typeConverter = TypeDescriptor.GetConverter(prop.PropertyType);
 cValue = typeConverter.ConvertFromString(Value);

我相信这可以帮助某人并使他免于愤怒的反对者。

【问题讨论】:

  • 为什么你不想使用string.Split(这正是你想要的)? 为什么你要使用TypeConverter(其中:默认不支持这种场景)。有注册自定义类型描述提供程序的方法,这些提供程序可以反过来提供自定义转换器,但是实现起来很复杂......这需要一个很好的理由
  • “我想要一些东西来吃汤,但不要给我勺子!”
  • @PatrickHofman - 我错过了。使用Split 的绝对明显性让我对问题的其余部分视而不见。为什么.Split(',') 不是一个合适的解决方案?
  • @PatrickHofman - 也许有人可以使用 IL 和 System.Reflection.Emit 发布解决方案。
  • @Dr_klo 仅仅说“我想使用 TypeConverter”是不够的,从那时起就不可能给出一个明智的答案。例如,在大多数情况下:要做你想做的事,你需要一个TypeDescriptionProvider 和一个自定义的ICustomTypeDescriptor,并挂钩到几个注册 API。这不是微不足道的。可以做到,但知道自己想做什么以及为什么这样做,很重要。考虑到规模,如果没有上下文:真正可能的最正确答案是:“使用 string.Split”。

标签: c# string converter


【解决方案1】:

这很简单:你不能。

new ArrayConverter().CanConvertFrom(typeof(string));

返回 false。

您最好的选择是您自己提到的选项:string.Split,或者从 ArrayConverter 派生并实现您自己的:

public class StringArrayConverter : ArrayConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }

        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string s = value as string;

        if (!string.IsNullOrEmpty(s))
        {
            return ((string)value).Split(',');
        }

        return base.ConvertFrom(context, culture, value);
    }
}

最后,我还是用string.Split。当然,您可以提出我们自己的实现。

【讨论】:

  • 我不能在我的程序中直接使用Split,但是你关于派生类的解决方案是最好的,因为它不会破坏程序的 OOP 范式
  • 想知道 ArrayConverter 的意义何在,因为我们可以转换为字符串,但我们不能从字符串转换,这与其他基本的 .Net TypeConverter(例如 NullableConverter)不同。像 ArrayConverter 这样的接缝并不完整。
【解决方案2】:

你可以使用Regex.Matches:

string[] result =
  Regex.Matches("foo1,foo2,foo3", @",").Cast<Match>().Select(m => m.Value).ToArray();

编辑:我没有得到正确的正则表达式,但重点仍然存在。

【讨论】:

  • 鉴于 string.Split 旨在完全执行 OP 想要的操作,我不确定类似方法的更多奇特变体是否会增加很多...跨度>
  • @MarcGravell 好吧,OP 特别要求提供一个不使用string.Split 的解决方案,所以我建议了一种不同的方法。
猜你喜欢
  • 2011-06-18
  • 1970-01-01
  • 2017-11-27
  • 2018-03-08
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多