C# 中的表达式主体成员
表达式主体成员提供了一个最小和简洁的语法来定义属性和方法。它有助于消除样板代码并有助于编写更具可读性的代码。当成员的主体仅由一个表达式组成时,可以使用表达式主体语法。它使用=> (f at arrow )运算符来定义方法或属性的主体,并允许摆脱大括号和return关键字。该功能最初是在 C# 6 中引入的。
表达体方法
在 C# 中,方法是执行给定任务并将结果返回给调用者的语句的集合。很多时候,方法最终只包含一条语句。例如,考虑以下代码:
int GetRectangleArea(int length, int breadth)
{
return length * breadth;
}
上面的方法只包含一个 return 语句。使用表达式体语法,上述方法可以改写如下:
int GetRectangleArea(int length, int breadth) => length * breadth;
请注意,没有大括号和return语句。已使用=>运算符而不是大括号。 return语句之后的表达式紧跟在=>运算符。
句法
[access-modifier] [qualifiers] return-type MethodName([parameters]) => expression;
例子
下面的示例定义了一个名为IsEven()的布尔方法,如果传递给它的数字是偶数,则该方法返回 true,否则,该方法返回 false。 IsEven()方法使用表达式主体语法。
C#
// C# program to illustrate expression bodied method
using System;
class GFG{
// Returns true if number is even
// else returns false
public static bool IsEven(int number) => number % 2 == 0;
// Driver code
public static void Main()
{
int n = 10;
if (IsEven(n))
{
Console.WriteLine("{0} is even", n);
}
else
{
Console.WriteLine("{0} is odd", n);
}
}
}
C#
// C# program to illustrate expression bodied properties
using System;
public class Square
{
private int side;
public Square(int side)
{
this.side = side;
}
public int Side => side;
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square(4);
Console.WriteLine($"Side is {square.Side}");
}
}
C#
// C# program to illustrate expression bodied properties
using System;
public class Square
{
private int side;
public int Side
{
get => side;
set => side = value;
}
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square{Side = 4};
Console.WriteLine($"Side is {square.Side}");
square.Side = 10;
Console.WriteLine($"Side is now {square.Side}");
}
}
C#
// C# program to illustrate expression-bodied
// constructors and destructors
using System;
public class Square
{
private int side;
public Square(int side) => this.side = side;
~Square() => Console.WriteLine("Square's Destructor");
public int Side => side;
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square(4);
Console.WriteLine($"Side is {square.Side}");
}
}
C#
// C# program to illustrate expression-bodied indexers
using System;
public class ProgrammingLangs
{
private string[] languages =
{
"C#",
"C",
"C++",
"Python",
"Java"
};
public string this[int idx] => languages[idx];
}
class GFG{
// Driver code
public static void Main()
{
var langs = new ProgrammingLangs();
Console.WriteLine(langs[0]);
Console.WriteLine(langs[2]);
Console.WriteLine(langs[3]);
}
}
C#
// C# program to illustrate expression-bodied operator functions
using System;
public struct Complex
{
public int Real{get; set;}
public int Imaginary{get; set;}
public Complex(int real, int imaginary)
{
Real = real;
Imaginary = imaginary;
}
// Expression-bodied operator method
public static Complex operator + (
Complex c1, Complex c2) =>
new Complex(c1.Real + c1.Real,
c1.Imaginary + c2.Imaginary);
public override string ToString() =>
$"({Real}) + ({Imaginary}i)";
}
class GFG{
// Driver code
public static void Main()
{
var a = new Complex(3, 2);
var b = new Complex(1, 2);
var result = a + b;
Console.WriteLine($"{a} + {b} = {result}");
}
}
10 is even
表达式体的 Void 方法
void 方法是那些不包含return语句并且仅由单个语句组成的方法,也可以使用表达式主体的语法。例如,以下方法:
void PrintName(string name)
{
Console.WriteLine($"The name is {name}");
}
可以用表达式体语法编写如下:
void PrintName(string name) => Console.WriteLine($"The name is {name}");
表达体属性
属性访问器也只能有一个语句。使用表达式主体属性,可以简化此类属性定义。
1.只读属性
只读属性是只有一个get访问器的属性,如下所示:
public int Name
{
get
{
return "Geeks For Geeks";
}
}
使用表达式主体语法,属性可以定义如下:
public int Name => "Geeks For Geeks";
句法
[access-modifier] [qualifier] type PropertyName => expression;
例子
下面的示例定义了一个名为Square的类,其构造函数接受正方形的边长。一旦在构造函数中设置了 side,就不能修改它,因为 public Side属性是只读的。此外, side字段是私有的,不能从类外部访问。
C#
// C# program to illustrate expression bodied properties
using System;
public class Square
{
private int side;
public Square(int side)
{
this.side = side;
}
public int Side => side;
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square(4);
Console.WriteLine($"Side is {square.Side}");
}
}
Side is 4
2. 非只读属性
从 C# 7 开始,非只读属性也可以具有表达式主体的get和set访问器。在下面的Person类中, Name属性定义了get和set访问器,每个访问器都只有一个语句:
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
这可以通过使用表达式主体访问器来简化:
public class Person
{
private string name;
public string Name
{
get => name;
set => name = value;
}
}
句法
[access-modifier] [qualifiers] [type] PropertyName
{
get => expression;
set => expression;
}
例子
下面的代码像上面的例子一样定义了一个Square类,但在这里, Side 属性也有一个set访问器。此外,还使用了对象初始值设定项而不是构造函数来为Side属性提供初始值:
C#
// C# program to illustrate expression bodied properties
using System;
public class Square
{
private int side;
public int Side
{
get => side;
set => side = value;
}
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square{Side = 4};
Console.WriteLine($"Side is {square.Side}");
square.Side = 10;
Console.WriteLine($"Side is now {square.Side}");
}
}
Side is 4
Side is now 10
表达式体构造函数和析构函数
表达式主体的语法也已扩展为与构造函数和析构函数/终结器一起使用。如果这些方法中的任何一个只包含一个语句,则它们可以被定义为表达式体。
句法
- 构造函数
[access-modifier] ClassName([parameters]) => expression;
- 析构函数/终结器
~ClassName() => expression;
例子
在下面的示例中, Square类定义了一个构造函数和析构函数,每个构造函数和析构函数都包含一个表达式主体的定义:
C#
// C# program to illustrate expression-bodied
// constructors and destructors
using System;
public class Square
{
private int side;
public Square(int side) => this.side = side;
~Square() => Console.WriteLine("Square's Destructor");
public int Side => side;
}
class GFG{
// Driver code
public static void Main()
{
var square = new Square(4);
Console.WriteLine($"Side is {square.Side}");
}
}
Side is 4
Square's Destructor
表达体索引器
与属性类似,索引器访问器也可以是表达式主体。索引器定义遵循与属性相同的约定,这意味着可以在不指定访问器的情况下定义只读索引器,并且读写访问器需要访问器的名称。
句法
- 只读索引器
[access-modifer] [qualifiers] return-type this[ [parameters] ] => expression;
- 读取和写入索引器
[access-modifier] [qualifiers] return-type this [ [parameters] ]
{
get => expression;
set => expression;
}
例子
下面的类ProgrammingLangs定义了编程语言的字符串数组语言,还定义了一个索引器,将索引转发到语言数组并返回该索引处的元素(语言)。索引器是只读的,因此不能在类之外修改数组中的语言。
C#
// C# program to illustrate expression-bodied indexers
using System;
public class ProgrammingLangs
{
private string[] languages =
{
"C#",
"C",
"C++",
"Python",
"Java"
};
public string this[int idx] => languages[idx];
}
class GFG{
// Driver code
public static void Main()
{
var langs = new ProgrammingLangs();
Console.WriteLine(langs[0]);
Console.WriteLine(langs[2]);
Console.WriteLine(langs[3]);
}
}
C#
C++
Python
表达式体运算符函数
就像带有单个语句的普通方法可以是表达式主体一样,如果它们的主体由单个语句组成,运算符方法定义也可以是表达式主体。
句法
[access-modifier] static operator [operator-symbol] ([parameters]) => expression;
例子
下面的示例实现了一个类 Complex,它表示复数的实部和虚部,还定义了二元 +运算符以允许将两个Complex对象相加。 operator+函数是表达式主体。
C#
// C# program to illustrate expression-bodied operator functions
using System;
public struct Complex
{
public int Real{get; set;}
public int Imaginary{get; set;}
public Complex(int real, int imaginary)
{
Real = real;
Imaginary = imaginary;
}
// Expression-bodied operator method
public static Complex operator + (
Complex c1, Complex c2) =>
new Complex(c1.Real + c1.Real,
c1.Imaginary + c2.Imaginary);
public override string ToString() =>
$"({Real}) + ({Imaginary}i)";
}
class GFG{
// Driver code
public static void Main()
{
var a = new Complex(3, 2);
var b = new Complex(1, 2);
var result = a + b;
Console.WriteLine($"{a} + {b} = {result}");
}
}
输出:
(3) + (2i) + (1) + (2i) = (6) + (4i)