前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NET问答:什么场景下应该选择 struct 而不是 class ?

NET问答:什么场景下应该选择 struct 而不是 class ?

作者头像
zls365
发布2021-04-23 11:39:57
4050
发布2021-04-23 11:39:57
举报
文章被收录于专栏:CSharp编程大全

咨询区

  • 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 点。

代码语言:javascript
复制

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 文件。

代码语言:javascript
复制

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

输出结果:

代码语言:javascript
复制

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CSharp编程大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 咨询区
  • 回答区
  • 点评区
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档