📜  C# 中的表达式主体成员

📅  最后修改于: 2022-05-13 01:55:15.986000             🧑  作者: Mango

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语句之后的表达式紧跟在=>运算符。

句法



例子

下面的示例定义了一个名为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";

句法

例子

下面的示例定义了一个名为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 开始,非只读属性也可以具有表达式主体的getset访问器。在下面的Person类中, Name属性定义了getset访问器,每个访问器都只有一个语句:

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;
    }
}

句法

例子

下面的代码像上面的例子一样定义了一个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

表达式体构造函数和析构函数

表达式主体的语法也已扩展为与构造函数和析构函数/终结器一起使用。如果这些方法中的任何一个只包含一个语句,则它们可以被定义为表达式体。



句法

  • 构造函数
  • 析构函数/终结器

例子

在下面的示例中, 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

表达体索引器

与属性类似,索引器访问器也可以是表达式主体。索引器定义遵循与属性相同的约定,这意味着可以在不指定访问器的情况下定义只读索引器,并且读写访问器需要访问器的名称。

句法

  • 只读索引器
  • 读取和写入索引器

例子

下面的类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

表达式体运算符函数

就像带有单个语句的普通方法可以是表达式主体一样,如果它们的主体由单个语句组成,运算符方法定义也可以是表达式主体。

句法

例子

下面的示例实现了一个类 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)