【问题标题】:C#, struct vs class, faster? [duplicate]C#,结构与类,更快? [复制]
【发布时间】:2011-11-21 00:49:16
【问题描述】:

可能重复:
Which is best for data store Struct/Classes?

考虑我有一个 Employee 对象的示例,该对象具有年龄、姓名、性别、职位、薪水等属性。我现在有一个列表,我想用一堆员工填充(每个员工实例都是唯一的)。

就速度和内存占用而言,将员工创建为结构还是类更可取?

欢迎对上述场景中的 Struct 与 Class 提出任何其他警告

【问题讨论】:

标签: c# class struct


【解决方案1】:

结构仅用于应该具有类似值的行为的相对较小的结构。

除非类型具有以下所有条件,否则不要定义结构 特点

  • 它在逻辑上表示单个值,类似于原始类型 (整数、双精度等)。
  • 它的实例大小小于 16 字节。
  • 它是不可变的。
  • 不必经常装箱。

您的类型违反了前两个准则,并且可能还违反了第三个准则。所以你绝对应该在这里使用一个类。

【讨论】:

  • It will not have to be boxed frequently. 这是什么意思?
  • @alex 请参阅docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/… 基本上,这意味着将 struct 转换为将导致它被堆分配的类型。 (将作为指针类型的值的结构转换为对象,或由该结构实现的任何接口)
  • 如何确定实例的大小?
  • @AntarrByrd 好问题。我认为获得想法的一种非常有保证的方法是确定字段的大小。例如,如果 int 是 4 个字节,那么,假设所有结构的字段都是 ints,则该结构最多应该有 4 个 (int) 字段(4 个字段 * 4 个字节 = 16 个字节)。
  • 这根本不能回答问题。问题是关于“速度和内存占用”,而不是最佳编码实践。
【解决方案2】:

这取决于,在这种情况下,可能一个类就可以了。希望以下几点能帮助您做出决定。

在以下情况下使用结构是可取的。

当你有小的数据结构时

数据结构不需要扩展功能。

当您想对数据结构执行更快的操作时。 (由于结构存储在堆栈中,因此对其执行的操作更快。)

在以下情况下使用类是可取的。

当你有复杂的数据结构时

数据结构需要扩展功能。

当您想要优化内存使用时。 (由于类存储在堆上,当没有指向对象的引用时,它们将被垃圾回收。)

查看here了解更多详情。

【讨论】:

    【解决方案3】:

    事情没有那么简单——你需要描述行为。例如,struct 会在您喜欢时立即复制自己,因此在某些方面它们会消耗更多内存。但是,将结构数组作为原始数据转储可以避免(非常小的)对象头(和额外的取消引用),因此可以提高效率。

    不过,更大的问题在于您如何将它们概念化; Employee 不是一个;如果我分配:

    var emp = GetEmployee();
    var tmp = emp;
    

    这是否意味着我现在应该有 2 名员工?它可能没有。现在如果我改变了怎么办:

    tmp.Name = "Fred";
    

    这是否影响emp 取决于它是结构还是类。我打赌它应该在这里上课。我还建议结构应该几乎始终是不可变的,以避免这种类型的数据丢失情况。可变结构是有道理的,但它经常被错误地使用,所以我不想意外地鼓励你这样做。

    使用结构封装会出现其他问题;认为员工有经理;这可能吗?

    [struct|class] Manager {
        private Manager boss;
    }
    

    这仅适用于类。再次;结构不太适合这种用法。也不是多态、抽象等。

    【讨论】:

    • 从概念上讲,我认为值类型语义在很多方面都比结构语义更清晰。给定一个类似 Rectangle 的结构数组,“ArrayOfRect[3].Width = 34;”的效果很清楚,因为根据定义,数组的每个元素都指向一个不同的 Rectangle 实例。假设一个人有一个矩形类的数组,并希望元素 3 具有与现在相同的属性,除了宽度为 34。如何去做呢?
    • @supercat 你的评论不清楚,因为 value-type===struct (你对比这两者);此外,可变结构 (ArrayOfRect[3].Width = 34;) 几乎总是一个非常糟糕的主意,并且会导致出现微妙问题的场景。最后一个问题......呃,完全按照你的例子,除了一个类,这不是一件坏事。
    • 我以为我是在对比结构和类,并表明结构数组的语义比类数组更清晰。 Lippert 先生非常鄙视可变结构,因为 .net 处理它们的方式存在一些怪癖和限制,但它们并不是一个“非常糟糕的主意”。除了一些(通常是人为的)罕见异常之外,关于可变结构状态的所有语义上有趣的东西都是由其字段的内容定义的。相比之下,对象的状态通常在很大程度上取决于存在对其的引用
    • 如果 GetEmployeeInfo 函数返回一个 EmployeeInfo 普通旧数据结构,那么对返回的结构进行变异的效果是毫无疑问的。对结构所做的更改将影响该副本,而不会影响其他任何内容。数据类型完全定义了语义。假设 GetEmployeeInfo 返回了一个可变类。数据源和返回的 EmployeeInfo 实例之间存在什么联系?对一个的更改会更新另一个,破坏另一个,还是对另一个没有影响?可能需要检查大量代码才能真正确定。
    • @supercat IMO,“普通旧数据结构”已经用词不当。结构最好保留给,而不是对象。
    猜你喜欢
    • 2011-06-15
    • 2010-10-07
    • 2011-02-14
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多