【问题标题】:Implicit Conversion to IEnumerable<T>隐式转换为 IEnumerable<T>
【发布时间】:2013-06-19 13:42:18
【问题描述】:

我有一个用于保存从配置文件加载的值的类。为了使这个类更易于使用,我设置了许多对一些基本类型的隐式转换。

我想转换成的类型之一是 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# c#-4.0 generics ienumerable implicit-conversion


【解决方案1】:

但这给了我 T 未定义的语法错误。没有办法定义这样的转换还是有特殊的语法?

您正在尝试声明一个泛型运算符 - 这在 C# 中不受支持。 (不知道 IL 中是否支持。)构造函数、属性、事件和终结器也是如此。

基本上,只有方法和类型可以是泛型的。

编辑:如 cmets 中所述,我会编写一个通用方法。用户定义的转换 - 特别是隐式转换 - 应该非常谨慎使用,IMO。

【讨论】:

  • 感谢您的快速回复,您是否建议为我想要支持的每种类型定义一个隐式 IEnumerable, ,或者您可以推荐一些更简洁的东西
  • @MaxEhrlich:我可能会写一个通用的 method 而不是隐式转换 - 我真的不喜欢隐式转换,尤其是那些试图“聪明”的转换"。
  • 明白了,我会尝试两者。我同意你关于隐式转换的观点,这是我唯一一次使用它们。将这些配置值视为具有正确的类型而不是需要转换的东西是很好的。
  • +1 建议非常谨慎地使用用户定义的转换
【解决方案2】:

您可以创建扩展方法,而不是通用运算符(正如@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>();

【讨论】:

    【解决方案3】:

    正如 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多