NET问答:什么场景下应该选择 struct 而不是 class ?
dotNET跨平台 今天
以下文章来源于NET技术问答 ,作者overflow
咨询区
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.18362Intel 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
赞 (0)