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)

相关推荐