2

I need convert string "foo1,foo2,foo3" to string[].

I want to use TypeConverter or its child ArrayConverter. Its contain method ConvertFromString.

But if I call this method I catch an exception ArrayConverter cannot convert from System.String.

I know about Split, don't suggest me this solution.

----SOLUTION---

using advice @Marc Gravell and answer of this topic by @Patrick Hofman I wrote 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();
        }
    }

where StringArrayConverter is implemented in answer below this post. To use it I added CustumTypeDescriptorProvider to collection of providers

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

To use it in TestClass you need to write a few lines:

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

I believe that this can help somebody and save him from angry downvoiters.

Dr_klo
  • 469
  • 6
  • 19
  • 2
    *why* don't you want to use `string.Split` (which does exactly what you want)? *why* do you want to use `TypeConverter` (which: does not support this scenario by default). There are ways of registering custom type description providers which can in turn provide custom converters, but that it a convoluted mess to implement... it would need a very good reason – Marc Gravell Dec 17 '15 at 08:47
  • `string[] result = "foo1,foo2,foo3".Split(',');` – Enigmativity Dec 17 '15 at 08:48
  • @Enigmativity OP knows that. He says in his post he doesn't want to use that... "I know about split, dont suggest me this solution." – Patrick Hofman Dec 17 '15 at 08:48
  • 2
    "I want some item to eat soup, but don't suggest me a spoon!" – Jcl Dec 17 '15 at 08:50
  • Note that `[TypeConverter(...)]` can be specified on member properties, so if this is for use in a `PropertyGrid` or similar, a custom `TypeConverter` could be *fairly* easy to implement; but if you need it to work from `TypeDescriptor.GetConverter(typeof(string[]))`: it will be much more complex – Marc Gravell Dec 17 '15 at 08:50
  • 1
    @PatrickHofman - I missed that. The completely overwhelmingly obviousiness of using `Split` blinded me to the rest of the question. Why o' why isn't `.Split(',')` a suitable solution? – Enigmativity Dec 17 '15 at 08:50
  • 2
    @PatrickHofman - Perhaps someone can post a solution using IL and `System.Reflection.Emit`. – Enigmativity Dec 17 '15 at 08:51
  • I ask concrete question: I want to use TypeConverter. It is specific of my program and I know about alternative ways. so your discussion is offtopic. Downvotes: your vote is concrete about question or philosophic "why you not use `split`"? – Dr_klo Dec 17 '15 at 09:04
  • 1
    @Dr_klo it isn't really sufficient to just say "I want to use TypeConverter", and it is impossible to give a sensible answer from that point. For example, in most scenarios: to do what you want, you would need a `TypeDescriptionProvider` and a custom `ICustomTypeDescriptor`, and hook into several registration APIs. It *isn't trivial*. It can be done, but knowing what you want to do, and why, **is important**. And given the scale, without that context: the most correct answer possible genuinely is: "use string.Split". – Marc Gravell Dec 17 '15 at 09:17
  • @MarcGravelI'm not looking for a simple way. It is condition of my program. And if I could use `Split` I would not ask a stupid question – Dr_klo Dec 17 '15 at 09:32
  • @MarcGravell - reason for not using split could be to support generically converting any types in a polymorphic way (split breaks the mold) but see my comment to dr_klo... – FastAl Feb 11 '19 at 18:24
  • @dr_klo, I can think of reasons, but after all this guff, why not just tell us? I am dying to know the reason :-) BTW I upvoted because I learned something from this post. Not because I like being kept in the dark. Lose the pride dude :-) people are helping your for free! – FastAl Feb 11 '19 at 18:25
  • @FastAl You want to know about reason, why I didn't use `split`? Your previous comment has right suggestion. I had been writing general converter for communication protocol, and I had been needed an beauty polymorphic solution. – Dr_klo Feb 13 '19 at 06:03

2 Answers2

8

It is quite simple: You can't.

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

returns false.

Your best option is the option you mentioned yourself: string.Split, or derive from ArrayConverter and implement your own:

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);
    }
}

In the end, I still use string.Split. You can come up with our own implementation of course.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • I cannot use directly `Split` in my program, but your solution about derived class is best because it isn't break OOP paradigms of the program – Dr_klo Dec 17 '15 at 09:33
  • Wonder what was the point of ArrayConverter since we CAN convert to string but we CAN'T from string, unlike other basic .Net TypeConverters (for example NullableConverter). Seams like ArrayConverter is not complete. – SoLaR Jul 30 '19 at 07:11
0

You can use Regex.Matches:

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

Edit: I didn't get the regex right, but the main point still stands.

Umut Seven
  • 398
  • 2
  • 11
  • 20
  • 2
    given that `string.Split` is intended to do **exactly** what the OP wants, I'm not sure that even more exotic variants of similar approaches add much... – Marc Gravell Dec 17 '15 at 08:46
  • @MarcGravell Well, OP _specifically_ asked for a solution that didn't use `string.Split`, so I suggested a different way to do it. – Umut Seven Dec 17 '15 at 08:50