如果可能,我想定义一个函数,例如作为累加器,它可以按如下方式无限链接:

  • f(2)返回2
  • f(2)(3)退货5
  • f(2)(3)(10)返回15
  • f(2)(3)(10)(100)返回115
  • f(2)(3)(10)(100)()()...个退货...
static void Main()
{
    Func<int, Func<int, int>> f = (x) =>
    {
        return (y) =>
        {
            return x += y;
        };
    };

    Console.WriteLine(f(2)(3));
    // Console.WriteLine(f(2)(3)(10)); should return 15

}

有什么主意吗?

注:我并不是要求f(param int[] x){}人接近.

推荐答案

f不能返回int,因为调用f一次后不能调用int.不过,它可以返回包装int的包装类型.f只需要返回包装器类型,然后就可以无限链接.

如果您对索引器访问语法[...]而不是方法调用语法(...)感到满意,那么您只需创建一个 struct ,如下所示:

struct F {
    public int Count { get; }
    
    private F(int count) {
        Count = count;
    }
    public F this[int acc] => new F(Count + acc);

    // override ToString to return Count.ToString,
    // or an implicit conversion to int, if you want
}

然后,

F f = new F(); // this could be a static field somewhere, making it effectively a global variable
Console.WriteLine(f[1][2][3][4].Count);

如果您真的喜欢方法调用语法,则需要使用dynamic并从DynamicObject继承,覆盖TryInvoke,就像在this answer中一样.

示例:

dynamic f = new F();
Console.WriteLine(f(1)(2)(3)(4).Count);

class F: DynamicObject {
    public int Count { get; }
    public F(int count = 0) {
        Count = count;
    }
    public override Boolean TryInvoke(InvokeBinder binder, object?[]? args, out object? result) {
        if (args?.Length == 1 && args?[0] is int acc) {
            result = new F(Count + acc);
            return true;
        }
        result = null;
        return false;
    }
}

Csharp相关问答推荐

Dapper是否可以自动扩展类成员

我需要两个属性类吗

不仅仅是一个简单的自定义按钮

Appsettings.json未加载.Net 8 Blaazor Web程序集

在实体框架中处理通用实体&S变更跟踪器

如何使用XmlSerializer序列化带有CDATA节的XML文件?

C#带主体的主构造函数?

异步任务调用程序集

如何在.NET AOT中为所有枚举启用JsonStringEnumConverter

如何实现有条件的自定义Json转换器隐藏属性

为什么Azure函数(独立工作进程)索引失败?使用Azure App配置的CosmosDbTrigger绑定失败,未解析为值

序列化过程中的死循环

C#System.Commandline:如何向命令添加参数以便向其传递值?

c#在后台实现类型化数组

如何在使用Google.Drive.apis.V3下载文件/文件夹之前压缩?

ASP.NET核心8:app.UseStaticFiles()管道执行顺序

C#中的逻辑运算符用作单词';is';and';and';

反编译源代码时出现奇怪的字符

方法加载时出现类型加载异常

GMap.NET中的暗模式映射