MSDN说当需要轻量级对象时应该使用结构。在其他情况下,结构体比类更可取吗?

有些人可能已经忘记了:

结构可以有方法。 结构不能被继承。

我理解结构体和类之间的技术差异,我只是对什么时候使用结构体没有很好的感觉。


当前回答

MSDN给出了答案: 在类和结构之间选择。

基本上,这个页面给你一个4项清单,并告诉你使用一个类,除非你的类型满足所有的标准。

不定义结构,除非 类型包含以下所有内容 特点: 它在逻辑上表示一个值,类似于基本类型 (整数,双精度,等等)。 实例大小小于16字节。 它是不可变的。 它不需要经常装箱。

其他回答

当您不需要行为,但需要比简单的数组或字典更多的结构时。

跟进 这就是我对结构体的一般看法。我知道他们可以有方法,但我喜欢保持整体的精神区分。

我认为最好的答案就是当你需要的是属性的集合时使用struct,当你需要的是属性和行为的集合时使用class。

除了以上精彩的回答:

结构是值类型。

它们永远不能被设置为“无”。

设置一个结构= Nothing,将其所有的值类型设置为默认值。

这是一个老话题,但希望提供一个简单的基准测试。

我已经创建了两个。cs文件:

public class TestClass
{
    public long ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

and

public struct TestStruct
{
    public long ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

运行基准:

创建一个TestClass 创建一个TestStruct 创建100个TestClass 创建100个TestStruct 创建10000个TestClass 创建10000 TestStruct

结果:

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.101
[Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT  [AttachedDebugger]
DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT


|         Method |           Mean |         Error |        StdDev |     Ratio | RatioSD | Rank |    Gen 0 | Gen 1 | Gen 2 | Allocated |
|--------------- |---------------:|--------------:|--------------:|----------:|--------:|-----:|---------:|------:|------:|----------:|

|      UseStruct |      0.0000 ns |     0.0000 ns |     0.0000 ns |     0.000 |    0.00 |    1 |        - |     - |     - |         - |
|       UseClass |      8.1425 ns |     0.1873 ns |     0.1839 ns |     1.000 |    0.00 |    2 |   0.0127 |     - |     - |      40 B |
|   Use100Struct |     36.9359 ns |     0.4026 ns |     0.3569 ns |     4.548 |    0.12 |    3 |        - |     - |     - |         - |
|    Use100Class |    759.3495 ns |    14.8029 ns |    17.0471 ns |    93.144 |    3.24 |    4 |   1.2751 |     - |     - |    4000 B |
| Use10000Struct |  3,002.1976 ns |    25.4853 ns |    22.5920 ns |   369.664 |    8.91 |    5 |        - |     - |     - |         - |
|  Use10000Class | 76,529.2751 ns | 1,570.9425 ns | 2,667.5795 ns | 9,440.182 |  346.76 |    6 | 127.4414 |     - |     - |  400000 B |

当您需要值类型语义而不是引用类型时,请使用结构。结构体是按值复制的,所以要小心!

另见以前的问题,例如:

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