V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lxilu
V2EX  ›  C#

Java Stream.iterate() generate() builder() C#怎么搞?

  •  
  •   lxilu · 2020-07-04 21:12:37 +08:00 · 4544 次点击
    这是一个创建于 1601 天前的主题,其中的信息可能已经有所发展或是发生改变。
    顺便,C# void List.Add() 怎么搞成链式调用?
    若要自己写扩展方法有什么好的实践?
    5 条回复    2020-10-03 20:58:22 +08:00
    AntiGameZ
        1
    AntiGameZ  
       2020-07-05 04:06:11 +08:00
    关键词 LINQ 。

    网上搜 “Java Stream 和 C# LINQ 比较” 应该也能给你很多资料。

    void List.Add(),既然返回值是 void 了,没法链式调用呀。
    lxilu
        2
    lxilu  
    OP
       2020-07-05 10:51:31 +08:00
    其它方法我都找到了对应,唯有这三个不知道。
    我要问的就是返回 void 怎么搞成链式调用啊。
    lxilu
        3
    lxilu  
    OP
       2020-07-05 10:53:10 +08:00
    AntiGameZ
        4
    AntiGameZ  
       2020-07-05 13:16:52 +08:00   ❤️ 1
    Stream.iterate(), Stream.generate()
    > Enumerable.Range(1, 100).Select(x => x * x);

    如果你要无限流的话,可以自己写个。我不知道有没有新的语法糖可以开箱即用。
    IEnumerable<T> InfiniteStream<T>()
    {
    while (true) { yield return default(T); }
    }

    Stream.builder() 的话,c# 直接支持集合类型的各种花式 initializer, .Select() 也可以通过直接创建匿名或非匿名对象达到这样的目的。

    --

    void List<T>.add() 因为返回值是 void,是不可能实现链式调用的,你需要的是一个 List<T> List<T>.add() 这样的扩展方法才行。现成可以用的应该是 IEnumerable<T> Enumerable.Concat<T>
    geelaw
        5
    geelaw  
       2020-10-03 20:58:22 +08:00   ❤️ 1
    很简单,使用一个 struct 包装之,在优化全开的情况下可以做到零额外开销:

    public static class Helper
    {
    public struct FluentList<T>
    {
    public readonly List<T> List;
    public FluentList(List<T> that) { List = that; }
    public FluentList<T> Add(T item) { List.Add(item); return this; }
    // Add other methods as needed.
    }
    public static FluentList<T> AsFluent<T>(this List<T> that) { return new FluentList<T>(that); }
    }

    // Consumer
    var list = new List<int>().AsFluent().Add(1).Add(2).List;

    另外生成无限默认值比较好的方法是自己写一个实现,很简单:

    public sealed class InfiniteStream<T> : IEnumerable<T>, IEnumerator<T>
    {
    public InfiniteStream<T> GetEnumerator() { return this; }
    public IEnumerator<T> IEnumerable<T>.GetEnumerator() { return this; }
    public IEnumerator IEnumerable.GetEnumerator() { return this; }

    public void Reset() { }
    public bool MoveNext() { return true; }
    public T Current { get { return default(T); } }
    public object IEnumerator.Current { get { return default(T); } }
    public void Dispose() { }

    private InfiniteStream() { }
    public static readonly InfiniteStream<T> Instance = new InfiniteStream<T>();
    }

    如果需要也可以写一个 struct 版本的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3014 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 13:26 · PVG 21:26 · LAX 05:26 · JFK 08:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.