原文: https://zetcode.com/lang/csharp/structures/

C# 教程的这一部分涵盖结构。

C# 结构定义

结构是值类型。 该类型由struct关键字定义。 结构与类非常相似。 它们在某些方面有所不同。 结构旨在表示轻量级对象,例如PointRectangleColor等。 在许多情况下,结构可能比类更有效。 结构是值类型,并在栈上创建。 注意,像intboolfloat之类的原始数据类型在技术上都是struct类型。

所有struct类型都继承自System.ValueType,并且继承自System.Object。 结构从来都不是抽象的,它们总是被隐式密封的。 因此结构类型不支持继承。 因此,不能将struct数据成员声明为受保护的。 struct定义不允许使用抽象修饰符和密封修饰符。 不允许struct声明无参数的构造器。

结构还可以包含构造器,常量,字段,方法,属性,索引器,运算符,事件和嵌套类型。 但是,如果我们需要实现更多这些功能,则可以考虑使用一个类。 结构可以实现接口。 struct可以用作nullable类型,并且可以分配为空值。

简单结构示例

以下示例创建一个简单的结构。

Program.cs

  1. using System;
  2. namespace SimpleStructure
  3. {
  4. public struct Point
  5. {
  6. private int x;
  7. private int y;
  8. public Point(int x, int y)
  9. {
  10. this.x = x;
  11. this.y = y;
  12. }
  13. public override string ToString()
  14. {
  15. return String.Format("Point x:{0}, y:{1}", x, y);
  16. }
  17. }
  18. class Program
  19. {
  20. static void Main(string[] args)
  21. {
  22. var p = new Point(2, 5);
  23. Console.WriteLine(p);
  24. }
  25. }
  26. }

该示例创建一个Point结构。 这个点也可以用一个类来表示,但是有了struct,我们的效率更高了。 特别是如果我们处理了很多问题。

  1. public struct Point
  2. {
  3. ...
  4. }

该结构用struct关键字声明。

  1. public override string ToString()
  2. {
  3. return String.Format("Point x:{0}, y:{1}", x, y);
  4. }

struct类型不支持继承。 但是,我们可以对方法使用override关键字,struct类型隐式地从中继承。 ToString()方法就是这种情况。

  1. var p = new Point(2, 5);
  2. Console.WriteLine(p);

我们创建Point结构,并在其上调用ToString()方法。

  1. $ dotnet run
  2. Point x:2, y:5

这是示例的输出。

没有new关键字

可以创建不带new关键字的struct类型的实例。

Program.cs

  1. using System;
  2. namespace NoNewKeyword
  3. {
  4. public struct Person
  5. {
  6. public string name;
  7. public int age;
  8. }
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. Person p;
  14. p.name = "Jane";
  15. p.age = 17;
  16. Console.WriteLine("{0} is {1} years old",
  17. p.name, p.age);
  18. }
  19. }
  20. }

我们有一个Person结构,其中有两个公共成员。

  1. Person p;

首先,我们声明一个Person结构。

  1. p.name = "Jane";
  2. p.age = 17;

稍后我们用一些数据初始化结构。

  1. $ dotnet run
  2. Jane is 17 years old

这是程序的输出。

C# 结构是值类型

结构类型是值类型。 它们是在栈上创建的。 创建值类型时,仅在内存中分配了一个空间来存储值。 值类型的分配将复制该值。

Program.cs

  1. using System;
  2. namespace ValueTypes
  3. {
  4. public struct Person
  5. {
  6. public Person(string name, int age) : this()
  7. {
  8. this.Name = name;
  9. this.Age = age;
  10. }
  11. public string Name { get; set; }
  12. public int Age { get; set; }
  13. public override string ToString()
  14. {
  15. return String.Format("{0} is {1} years old", Name, Age);
  16. }
  17. }
  18. class Program
  19. {
  20. static void Main(string[] args)
  21. {
  22. var p1 = new Person("Beky", 18);
  23. var p2 = p1;
  24. Console.WriteLine(p2);
  25. p2.Name = "Jane";
  26. p2.Age = 17;
  27. Console.WriteLine(p2);
  28. Console.WriteLine(p1);
  29. }
  30. }
  31. }

我们有一个带有两个数据成员的Person结构。 我们有两个参数的构造器,我们也使用自动属性。

  1. public string Name { get; set; }
  2. public int Age { get; set; }

可以在struct类型中使用自动属性。

  1. var p1 = new Person("Beky", 18);
  2. var p2 = p1;

在这里,我们创建一个struct。 然后将创建的struct分配给另一个struct。 我们创建该结构的副本。

  1. p2.Name = "Jane";
  2. p2.Age = 17;

我们更改第二个结构的数据。 第一个不受影响,因为我们正在处理原始struct类型的副本。

  1. $ dotnet run
  2. Beky is 18 years old
  3. Jane is 17 years old
  4. Beky is 18 years old

This is the output of the program.

基本类型是结构

intfloatbool之类的原始数据类型是内部结构。 这不同于 C++ 或 Java 之类的语言。

Program.cs

  1. using System;
  2. public class PrimitiveTypes
  3. {
  4. static void Main()
  5. {
  6. float x = 12.3f;
  7. int y = 34;
  8. bool z = false;
  9. Console.WriteLine(x.GetType());
  10. Console.WriteLine(y.GetType());
  11. Console.WriteLine(z.GetType());
  12. }
  13. }

我们有三个变量:floatintbool。 我们对它们每个调用GetType()方法。

  1. Console.WriteLine(x.GetType());

我们在浮点值上调用GetType()方法。 每个结构都隐式继承自包含GetType()方法的System.ValueType类。

  1. $ dotnet run
  2. System.Single
  3. System.Int32
  4. System.Boolean

这是示例的输出。 我们可以在文档中查找这些类型是结构。

在 C# 教程的这一部分中,我们介绍了结构。