【问题标题】:What's the best way to write [0..100] in C#?用 C# 编写 [0..100] 的最佳方法是什么?
【发布时间】:2010-09-16 16:42:38
【问题描述】:

我试图想出聪明、清晰和简单的方法来编写描述给定范围内整数序列的代码。

这是一个例子:

IEnumerable<int> EnumerateIntegerRange(int from, int to)
{
    for (int i = from; i <= to; i++)
    {
        yield return i;
    }
}

【问题讨论】:

    标签: c# linq optimization sequences


    【解决方案1】:

    或者,来自扩展方法的流畅接口:

    public static IEnumerable<int> To(this int start, int end)
    {
        return start.To(end, i => i + 1);
    }
    
    public static IEnumerable<int> To(this int start, int end, Func<int, int> next)
    {
        int current = start;
        while (current < end)
        {
            yield return current;
            current = next(current);
        }
    }
    

    类似:

    1.To(100)
    

    【讨论】:

    • 就个人而言,我更喜欢扩展方法的阅读方式。虽然,对于扩展方法,我确实有一些软弱的一面(我为 VB 实现了它们)。我一直不明白为什么 C# 的人一开始就不让 Range 成为扩展方法。
    【解决方案2】:

    如果你认为每次都提供枚举器很烦人,这里有一个派生类:

    class EnumerableRange<T> : Range<T>, IEnumerable<T>
        where T : IComparable<T>
    {
        readonly Func<T, T> _next;
        public EnumerableRange(T from, T to, Func<T, T> next)
            : base(from, to)
        {
            this._next = next;
        }
    
        public IEnumerator<T> GetEnumerator()
        {
            return Enumerate(this._next).GetEnumerator();
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
    

    【讨论】:

    • 我发现拥有 Range 类和不同的 RangeIterator 类提供了更好的分离。除此之外,这意味着您的 Range 可以是不可变的和密封的,这很好。 MiscUtil 中的版本有多种方法(扩展和其他)在两者之间进行。
    • 是的,我在 MiscUtil 中看到了那个。我的范围可能是不可变的;对我来说,可变性的唯一原因是它允许 C# 对象初始化器。我可能应该追求不变性。
    【解决方案3】:

    这是一个让范围类同时处理离散和非离散事物的想法:

    class Range<T> where T: IComparable<T>
    {
        public T From { get; set; }
        public T To { get; set; }
    
        public Range(T from, T to) { this.From = from; this.To = to; }
    
        public IEnumerable<T> Enumerate(Func<T, T> next)
        {
            for (T t = this.From; t.CompareTo(this.To) < 0; t = next(t))
            {
                yield return t;
            }
        }
    
        static void Example()
        {
            new Range<int> (0, 100).Enumerate(i => i+1)
        }
    }
    

    【讨论】:

      【解决方案4】:

      这已经在框架中了:Enumerable.Range

      对于其他类型,您可能对我的MiscUtil 库中的范围类感兴趣。

      【讨论】:

      • @Sam:对我有用,有什么不好的?
      • @Sam:哪一个不适合你,你得到了什么?
      • IEnumerable squares = Enumerable.Range(1, 10).Select(x => x * x); foreach (int num in squares) { Console.WriteLine(num);与(在 python 中):for i in range(10): print i 我喜欢编译语言如何向后弯曲,使简单的事情变得非常复杂。就像它越简单 - 编码就越难!
      • 嗯?在 C# 中可以是foreach(var i in Enumerable.Range(1, 10)) Console.WriteLine(i * i); ... range 和 print 函数的名称较长,并且 Range 需要一个 start 参数。没有除 i 以外的变量,没有 lambdas。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多