Max Ehrlich
Max Ehrlich

Reputation: 2525

Implicit Conversion to IEnumerable<T>

I have a class that is used to hold values loaded from a configuration file. To make this class easier to use, I have set up many implicit conversions to some basic types.

One of the types I would like to convert to is IEnumerable(T). For example, if the programmer has a value like this in the config file

a = "1,2,3,4"

In C# code, he can write

IEnumerable<int> a = Config.a;

Ideally what I would like to write is this

    public static implicit operator IEnumerable<T>(ConfigurationValue val)
    {
        string value = val;

        string[] parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        List<T> convertedTypes = new List<T>();

        foreach (string part in parts)
        {
            T converted = Convert.ChangeType(part.Trim(), typeof(T));
            convertedTypes.Add(converted);
        }

        return convertedTypes;
    }

But this is giving me syntax errors that T is undefined. Is there no way to define such a conversion or is there a special syntax for it?

Also for the record I am using C# 4.0 in the .Net Framework 4.0

Upvotes: 3

Views: 4307

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1500785

But this is giving me syntax errors that T is undefined. Is there no way to define such a conversion or is there a special syntax for it?

You're trying to declare a generic operator - and that's not supported in C#. (I don't know whether it's supported in IL.) The same is true for constructors, properties, events and finalizers.

Basically, only methods and types can be generic.

EDIT: As noted in comments, I'd write a generic method instead. User-defined conversions - particularly implicit ones - should be used very sparingly, IMO.

Upvotes: 9

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236228

Instead of generic operator (which is impossible as @Jon stated) you can create extension method:

public static IEnumerable<T> AsEnumerable<T>(this string value)
{
    if (String.IsNullOrEmpty(value))
        yield break;

    var parts = value.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);

    foreach (string part in parts)
        yield return Convert.ChangeType(part.Trim(), typeof(T));
}

And use it like this:

IEnumerable<int> a = Config.a.AsEnumerable<int>();

Upvotes: 5

Dustin Kingen
Dustin Kingen

Reputation: 21245

As Jon Skeet mentioned generic operators aren't supported, but you could make it a generic extension method instead.

public static class ConfigurationExtensions
{
    public IEnumerable<T> GetValues<T>(this ConfigurationValue val)
    {
        string value = val.Value;

        string[] parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        List<T> convertedTypes = new List<T>();

        foreach (string part in parts)
        {
            T converted = (T)Convert.ChangeType(part.Trim(), typeof(T));
            convertedTypes.Add(converted);
        }

        return convertedTypes;
    }
}

Upvotes: 2

Related Questions