咨询区
Esteban Araya:
MSDN 上说当你需要一个轻量级对象时应该选择 struct,说的含含糊糊,真的不知道有哪些场景下优先选择 struct 而不是 class。
可能有些人已经忘了。
struct 可以有方法。
struct 不能被继承。
我非常明白 struct 和 class 在技术上的不同,就是把不准什么场景下该使用它????????????...
回答区
Yashwanth Chowdary Kata:
使用 class 的情况
如果同一性非常重要,毕竟 struct 传递时是完整copy的。
如果需要占用很大内存。
如果你有
继承/多态
的需求。
使用 struct 的情况
如果你想使用基元类型 (int,long,byte ...)
如果你想精细的优化内存
如果 P/Invoke 必须传值类型。
如果你想减少 GC 的负载
如果没有
继承/多态
的需求。
Andrei Rînea:
申明一下,我没看过其他人的答案,我觉得最重要的方面是:当我需要一个无需 唯一标识
的类型时用 struct,比如说:3D
点。
public struct ThreeDimensionalPoint
{public readonly int X, Y, Z;public ThreeDimensionalPoint(int x, int y, int z){this.X = x;this.Y = y;this.Z = z;}public override string ToString(){return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";}public override int GetHashCode(){return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);}public override bool Equals(object obj){if (!(obj is ThreeDimensionalPoint))return false;ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;return this == other;}public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2){return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;}public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2){return !(p1 == p2);}
}
值得注意的是,当用值类型替代引用类型后,当心 按值copy
的问题。
Eduardas Šlutas:
这是一个老话题了,我就提供一下 class 和 struct 的 benchmark 吧,有如下两个 .cs 文件。
public class TestClass
{public long ID { get; set; }public string FirstName { get; set; }public string LastName { get; set; }
}public struct TestStruct
{public long ID { get; set; }public string FirstName { get; set; }public string LastName { get; set; }
}
运行 benchmark:
Create 1 TestClass
Create 1 TestStruct
Create 100 TestClass
Create 100 TestStruct
Create 10000 TestClass
Create 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 |
点评区
确实这是一个老话题了,我一般在讲究内存优化的场景下,优先考虑 struct,毕竟 struct 没有 object 的 同步块索引 + 方法表指针
,在 64bit 机器上,光这块开销就是 16byte,如果再放大千万倍那可不得了????????????,其他的场景怎么搞都行。
原文链接:https://stackoverflow.com/questions/85553/when-should-i-use-a-struct-instead-of-a-class