协慌网

登录 贡献 社区

.NET 中的 struct 和 class 有什么区别?

.NET 中的 struct 和 class 有什么区别?

答案

在. NET 中,有两类类型,引用类型值类型

结构是值类型,类是引用类型

通常的区别是,引用类型驻留在堆上,而值类型驻留在内联中,也就是说,无论它在何处定义了变量或字段。

包含值类型的变量包含整个值类型值。对于结构,这意味着变量包含整个结构及其所有字段。

包含引用类型的变量包含指针或对实际值所在的内存中其他位置的引用。

首先有一个好处:

  • 值类型始终包含一个值
  • 引用类型可以包含null引用,这意味着它们目前根本不引用任何内容

在内部,引用类型s 被实现为指针,并且知道了这一点,并且知道了变量赋值的工作原理,还有其他行为模式:

  • 将值类型变量的内容复制到另一个变量中,然后将整个内容复制到新变量中,以使两者截然不同。换句话说,在复制后,对一个所做的更改不会影响另一个
  • 将引用类型变量的内容复制到另一个变量中,然后复制引用,这意味着您现在在实际数据的其他存储位置拥有两个相同的引用。换句话说,在复制之后,更改一个引用中的数据似乎也会影响另一个引用,但这仅仅是因为您实际上只是在两个地方查看相同的数据

声明变量或字段时,以下是两种类型的不同之处:

  • 变量:值类型驻留在堆栈上,引用类型驻留在堆栈上,作为指向实际内存所在的堆内存中某处的指针(尽管请注意Eric Lipperts 文章系列:堆栈是实现细节)
  • class / struct-field:值类型完全位于该类型内部,引用类型位于该类型内部,作为指向实际内存所在的堆内存中某处的指针。

每个的简短摘要:

仅限课程:

  • 可以支持继承
  • 是引用(指针)类型
  • 引用可以为空
  • 每个新实例都有内存开销

仅结构:

  • 无法支持继承
  • 是值类型
  • 按值传递(如整数)
  • 不能有空引用(除非使用了 Nullable)
  • 每个新实例没有内存开销 - 除非 “装箱”

类和结构:

  • 复合数据类型通常用于包含一些具有某种逻辑关系的变量
  • 可以包含方法和事件
  • 可以支持接口

在. NET 中,结构和类声明区分引用类型和值类型。

当您绕过一种引用类型时,实际上只存储一种。所有访问该实例的代码都在访问同一代码。

当您传递一个值类型时,每个值类型都是一个副本。所有代码都在自己的副本上工作。

可以用一个示例显示:

struct MyStruct 
{
    string MyProperty { get; set; }
}

void ChangeMyStruct(MyStruct input) 
{ 
   input.MyProperty = "new value";
}

...

// Create value type
MyStruct testStruct = new MyStruct { MyProperty = "initial value" }; 

ChangeMyStruct(testStruct);

// Value of testStruct.MyProperty is still "initial value"
// - the method changed a new copy of the structure.

对于一堂课,这将是不同的

class MyClass 
{
    string MyProperty { get; set; }
}

void ChangeMyClass(MyClass input) 
{ 
   input.MyProperty = "new value";
}

...

// Create reference type
MyClass testClass = new MyClass { MyProperty = "initial value" };

ChangeMyClass(testClass);

// Value of testClass.MyProperty is now "new value" 
// - the method changed the instance passed.

类不能为空 - 引用可以指向 null。

结构是实际值 - 它们可以为空,但不能为 null。因此,结构始终具有不带参数的默认构造函数 - 它们需要一个 “起始值”。