我认为这在F#中已经在某种程度上实现了|>运算符,但我喜欢用现有方法在C#中看到它,而不需要重写它们。我经常看到这样的代码:
var str = string.Join("|", Regex.Split(File.ReadAllText(@"C:\file.txt"),
@"EOL(\r\n?|\n)", RegexOptions.IgnoreCase).Where(s => s != ""));
str包含什么?您必须仔细查看括号并看到它首先读取文本文件,然后正则表达式将其拆分,然后删除空行,然后将它们连接在一起。他们编写的顺序经常与执行顺序相反。写这个更自然的是:
var str = File.ReadAllText(@"C:\file.txt")
|> Regex.Split(@"EOL(\r\n?|\n)", RegexOptions.IgnoreCase)
|> Where(s => s != "")
|> string.Join("|")
|> operator将传递前一个结果作为this
(对于Where())或作为第一个具有兼容类型的参数(对于Regex.Split()它是第一个参数,对于string.Join()它是第二个参数)用于下一个代码段。我们可以通过应用另一个语法糖来进一步简化代码:An idea for an implicit context-dependent operator . (dot) as syntactic sugar
var str = File.ReadAllText(@"C:\file.txt")
|> Regex.Split(@"EOL(\r\n?|\n)", .IgnoreCase)
|> Where(. != "")
|> string.Join("|")
在我看来,这比第一个代码更容易阅读,顺序是操作完成的真实顺序,因此它更符合逻辑。没有方法不需要重写,这适用于所有当前代码,只有|>运营商补充说这样我们就可以使用来自所有地方的方法,无论它们与类型的关系如何(作为该类型的方法,或者以接收该类型作为参数的方法)以简单的线性方式反映执行的顺序
编辑:我的问题是:您认为这会作为语法糖有用吗?
我会在这里继续添加一个东西 - 因为我们不再像第一个代码那样嵌套方法,我们可以完全使用括号,使代码更具可读性:
var str = File.ReadAllText @"C:\file.txt"
|> Regex.Split @"EOL(\r\n?|\n)", .IgnoreCase
|> Where . != ""
|> string.Join "|"
答案 0 :(得分:1)
如果你所关心的只是乱七八糟的嵌套括号,那么敲一下Pipe
扩展方法可以让你扁平化调用。
(它没有你所建议的语法糖和参数自动插入推理。在我看来,论证自动插入无论如何都是一个坏主意,并且会使代码 less 可以理解。)
var s = File.ReadAllText(@"c:\file.txt")
.Pipe(x => Regex.Split(@"EOL(\r\n?|\n)", x, RegexOptions.IgnoreCase))
.Where(x => x != "")
.Pipe(x => string.Join("|", x));
// ...
public static TOut Pipe<TIn, TOut>(this TIn source, Func<TIn, TOut> func)
{
if (func == null)
throw new ArgumentNullException("func");
return func(source);
}
答案 1 :(得分:0)
你提供的例子是完全混乱 在某些情况下,您使用new运算符,如普通点运算符。在其他情况下,您可以将其用作操作符后面的方法的第一个或的替代。这不是语法糖,因为没有固定的规则,你的新算子意味着什么。