.NET中的结构和类有什么区别?


当前回答

类中声明的事件通过锁(this)自动锁定其+=和-=访问,以使其线程安全(静态事件根据类的类型锁定)。结构中声明的事件没有自动锁定其+=和-=访问。结构的锁(this)无法工作,因为只能锁定引用类型表达式。创建结构实例不能导致垃圾收集(除非构造函数直接或间接创建引用类型实例),而创建引用类型的实例会导致垃圾收集。结构始终具有内置的公共默认构造函数。类DefaultConstructor{静态空隙Eg(){直接yes=新的直接();//始终编译正常InDirect可能=新InDirect();//如果构造函数存在且可访问,则编译//...}}这意味着结构总是可实例化的,而类可能不是,因为它的所有构造函数都可以是私有的。类不可实例化{private NonInstantiable()//确定{}}结构Direct{private Direct()//编译时错误{}}结构不能有析构函数。析构函数只是对象的重写。伪装完成,结构作为值类型,不受垃圾收集的影响。结构Direct{~Direct(){}//编译时错误}InDirect类{~InDirect(){}//编译正常}~Indirect()的CIL如下所示:.method家族hidebysig虚拟实例无效Finalize()cil已管理{// ...}//方法结束间接::Finalize结构是隐式密封的,类不是。结构不能是抽象的,类可以。结构不能在其构造函数中调用:base(),而没有显式基类的类可以。结构不能扩展另一个类,类可以。结构不能声明类可以声明的受保护成员(例如,字段、嵌套类型)。结构不能声明抽象函数成员,抽象类可以。结构不能声明虚函数成员,类可以。结构不能声明密封的函数成员,类可以。结构不能声明重写函数成员,类可以。此规则的一个例外是,结构可以重写System.Object的虚拟方法,即Equal()、GetHashCode()和ToString()。

其他回答

类中声明的事件通过锁(this)自动锁定其+=和-=访问,以使其线程安全(静态事件根据类的类型锁定)。结构中声明的事件没有自动锁定其+=和-=访问。结构的锁(this)无法工作,因为只能锁定引用类型表达式。创建结构实例不能导致垃圾收集(除非构造函数直接或间接创建引用类型实例),而创建引用类型的实例会导致垃圾收集。结构始终具有内置的公共默认构造函数。类DefaultConstructor{静态空隙Eg(){直接yes=新的直接();//始终编译正常InDirect可能=新InDirect();//如果构造函数存在且可访问,则编译//...}}这意味着结构总是可实例化的,而类可能不是,因为它的所有构造函数都可以是私有的。类不可实例化{private NonInstantiable()//确定{}}结构Direct{private Direct()//编译时错误{}}结构不能有析构函数。析构函数只是对象的重写。伪装完成,结构作为值类型,不受垃圾收集的影响。结构Direct{~Direct(){}//编译时错误}InDirect类{~InDirect(){}//编译正常}~Indirect()的CIL如下所示:.method家族hidebysig虚拟实例无效Finalize()cil已管理{// ...}//方法结束间接::Finalize结构是隐式密封的,类不是。结构不能是抽象的,类可以。结构不能在其构造函数中调用:base(),而没有显式基类的类可以。结构不能扩展另一个类,类可以。结构不能声明类可以声明的受保护成员(例如,字段、嵌套类型)。结构不能声明抽象函数成员,抽象类可以。结构不能声明虚函数成员,类可以。结构不能声明密封的函数成员,类可以。结构不能声明重写函数成员,类可以。此规则的一个例外是,结构可以重写System.Object的虚拟方法,即Equal()、GetHashCode()和ToString()。

类的实例存储在托管堆上。“包含”实例的所有变量都只是对堆上实例的引用。将对象传递给方法会导致传递引用的副本,而不是对象本身。

结构(从技术上讲,值类型)存储在使用它们的任何地方,很像原始类型。运行时可以随时复制内容,而无需调用自定义的复制构造函数。将值类型传递给方法涉及复制整个值,同样无需调用任何自定义代码。

C++/CLI名称使这种区别更加明显:“ref class”是第一个类,“value class”是第二个类。C#使用的关键字“class”和“struct”只是必须学习的东西。

为了使其完整,使用Equals方法时还有另一个不同之处,它由所有类和结构继承。

假设我们有一个类和一个结构:

class A{
  public int a, b;
}
struct B{
  public int a, b;
}

在Main方法中,我们有4个对象。

static void Main{
  A c1 = new A(), c2 = new A();
  c1.a = c1.b = c2.a = c2.b = 1;
  B s1 = new B(), s2 = new B();
  s1.a = s1.b = s2.a = s2.b = 1;
}

然后:

s1.Equals(s2) // true
s1.Equals(c1) // false
c1.Equals(c2) // false
c1 == c2 // false

因此,结构适用于类似数字的对象,例如点(保存x和y坐标)。课程适合其他人。即使两个人的名字、身高、体重。。。,他们还是两个人。

结构是实际值-它们可以为空,但不能为空

这是正确的,但是也要注意,从.NET2开始,结构支持Nullable版本,C#提供了一些语法糖,使其更易于使用。

int? value = null;
value  = 1;

我♥ 可视化,在这里我创建了一个来展示结构和类之间的基本区别。


以及文本表示,以防万一;)

+--------------------------------------------------+------+----------------------------------------------+
|                      Struct                      |      |                      Class                    |
+--------------------------------------------------+------+----------------------------------------------+
| - 1 per Thread.                                  |      | - 1 per application.                         |
|                                                  |      |                                              |
| - Holds value types.                             |      | - Holds reference types.                     |
|                                                  |      |                                              |
| - Types in the stack are positioned              |      | - No type ordering (data is fragmented).     |
|   using the LIFO principle.                      |      |                                              |
|                                                  |      |                                              |
| - Can't have a default constructor and/or        |      | - Can have a default constructor             |
|   finalizer(destructor).                         |      |   and/or finalizer.                          |
|                                                  |      |                                              |
| - Can be created with or without a new operator. |      | - Can be created only with a new operator.   |
|                                                  |      |                                              |
| - Can't derive from the class or struct          |  VS  | - Can have only one base class and/or        |
|   but can derive from the multiple interfaces.   |      |   derive from multiple interfaces.           |
|                                                  |      |                                              |
| - The data members can't be protected.           |      | - Data members can be protected.             |
|                                                  |      |                                              |
| - Function members can't be                      |      | - Function members can be                    |
|   virtual or abstract.                           |      |   virtual or abstract.                       |
|                                                  |      |                                              |
| - Can't have a null value.                       |      | - Can have a null value.                     |
|                                                  |      |                                              |
| - During an assignment, the contents are         |      | - Assignment is happening                    |
|   copied from one variable to another.           |      |   by reference.                              |
+--------------------------------------------------+------+----------------------------------------------+

有关更多信息,请查看以下内容:

类和结构(官方文档)。在类和结构之间选择(官方文档)。