gpt4 book ai didi

c# - Func 中的第一个箭头运算符是什么意思?

转载 作者:行者123 更新时间:2023-12-02 11:58:20 25 4
gpt4 key购买 nike

给出这个示例代码:

enum op
{
add,
remove
}

Func<op, int> combo(string head, double tail) =>
(op op) =>
op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) : Int32.Parse(head) - Convert.ToInt32(tail);

Console.WriteLine(combo("1", 2.5)(op.remove));

返回结果:

-1

第一个箭头运算符是什么意思?
根据规范,它看起来不像表达式体或 lambda 运算符。
C# language specification中有没有引用关于这个用法?

最佳答案

What does the first arrow operator mean?

在较新版本的 C# 中,您可以编写:

int M(int x) 
{
return x + x;
}

更短更清晰:

int M(int x) => x + x;

它只不过是一个“语法糖”,可以让你以更短、更直接的方式编写一个简单的方法。

it does not look like an expression body or a lambda operator.

左边的=>表示表达式主体。右侧的 => 表示 lambda。因此,在您的示例中有些令人困惑,因为返回的是 lambda,它也使用 =>。但不要让它分散你的注意力:

Func<int, int> M() => x => x + 1;

只是一种简短的写法

Func<int, int> M() 
{
return x => x + 1;
}

这又只是一条捷径或写作

static int Anonymous(int x)
{
return x + 1;
}
Func<int, int> M()
{
return Anonymous;
}

如果您发现具有多个 => 运算符的代码令人困惑,您可以随时通过将它们脱糖为更明确的形式来删除它们。这只是一些人认为更容易阅读的简短形式。

<小时/>

Can you please write

static Func<op, int> combo(string head, double tail) =>
(op op) => ...;

with just one => operator.

当然。以下是编写该代码的两种等效方法。

// Block body, lambda return.
static Func<op, int> combo(string head, double tail)
{
return (op op) => ...;
}

// Block body, local function return:
static Func<op, int> combo(string head, double tail)
{
op MyFunction(op)
{
return ...;
}
return MyFunction;
}

Sorry, I was not being explicit. What I meant was can you please extract the lambda into its own standalone function, like what one would do in the olden days.

当然;这有点复杂。我们将通过一系列小步骤来完成:

我们从这里开始:

Func<op, int> combo(string head, double tail) => 
(op op) =>
op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);

对外部函数进行脱糖:

Func<op, int> combo(string head, double tail)
{
return (op op) =>
op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);
}

将内部函数变成助手:

static int Helper(string head, double tail, op op)
{
return op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);
}

Func<op, int> combo(string head, double tail)
{
return (op op) => Helper(head, tail, op);
}

现在将辅助方法移至类中:

private class Closure
{
public int Helper(string head, double tail, op op)
{
return op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);
}
}

Func<op, int> combo(string head, double tail)
{
Closure c = new Closure();
return (op op) => c.Helper(head, tail, op);
}

现在制作闭包的头部和尾部成员:

private class Closure
{
public string head;
public double tail;
public int Helper(op op)
{
return op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);
}
}

Func<op, int> combo(string head, double tail)
{
Closure c = new Closure();
c.head = head;
c.tail = tail;
return (op op) => c.Helper(op);
}

现在我们可以对 lambda 进行脱糖处理:

private class Closure
{
public string head;
public double tail;
public int Helper(op op)
{
return op == op.add ? Int32.Parse(head) + Convert.ToInt32(tail) :
Int32.Parse(head) - Convert.ToInt32(tail);
}
}

Func<op, int> combo(string head, double tail)
{
Closure c = new Closure();
c.head = head;
c.tail = tail;
return c.Helper;
}

我们就完成了。

如果您使用 ILDASM 或 Sharplab.io 或某些此类工具反编译代码,您会发现这正是编译器为您的代码生成的内容,只是它为帮助程序生成奇怪的非法名称,以确保您不会意外错误地调用了其中之一。

关于c# - Func<T, TReturn> 中的第一个箭头运算符是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58597957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com