隐式转换为IEnumerable<T>

3
我是一个有用的助手,可以为您翻译文本。
我有一个类,用于保存从配置文件中加载的值。为了让这个类更易于使用,我设置了许多隐式转换到一些基本类型的方法。
其中一个我想要转换的类型是IEnumerable(T)。例如,如果程序员在配置文件中有以下值:
a = "1,2,3,4"

在C#代码中,他可以编写

IEnumerable<int> a = Config.a;

理想情况下,我想要写成这样。
    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;
    }

但是这样会给我带来语法错误,提示 T 未定义。是否没有办法定义这样的转换,还是有特殊的语法?

另外,记录一下,我正在使用 .Net Framework 4.0 中的C# 4.0。


可能是重复问题 C# 泛型运算符 - Dustin Kingen
3个回答

9
但是这给了我语法错误,T未定义。有没有办法定义这样的转换或者有特殊的语法吗?您正在尝试声明一个通用运算符-在C#中不支持(我不知道它是否在IL中支持)。构造函数、属性、事件和终结器也是如此。基本上,只有方法和类型可以是通用的。编辑:如评论中所述,我会编写一个通用方法。用户定义的转换-特别是隐式转换-在我看来应该非常谨慎使用。

谢谢您的快速回复,您是否建议为我想要支持的每种类型定义一个隐式的IEnumerable<int>,<string>,...,还是有更简洁的建议? - Max Ehrlich
@MaxEhrlich:我可能会编写一个通用的方法,而不是隐式转换——我真的不喜欢隐式转换,特别是那些试图变得“聪明”的转换。 - Jon Skeet
明白了,我会尝试两种方法。我同意你关于隐式转换的看法,这也是我唯一使用它们的时候。把这些配置值视为具有适当类型而不是需要转换的东西是很好的想法。 - Max Ehrlich
1
建议非常谨慎地使用用户定义的转换,以此获得推荐的+1。 - Sergey Berezovskiy

5

你可以创建扩展方法来代替通用运算符(正如@Jon所述,这是不可能的):

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

并像这样使用:

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

2
正如Jon Skeet所提到的,泛型运算符是不被支持的,但您可以将其作为泛型扩展方法来实现。
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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接