C# 哪个最适合数据存储结构/类?
我们在SO中看到了很多关于c#中类与结构的讨论。大多数结论是,这是一个堆/堆栈内存分配。并建议在小数据结构中使用structs 现在,我有一个情况来决定这两个选择中的简单数据存储。目前,在我们的应用程序中,我们有数千个类,只是充当简单的数据存储(仅公开的公共字段),它们在不同的模块和服务之间传递 根据我的理解,出于性能方面的考虑,我觉得最好还是使用struct而不是类。因为这些都是简单的数据结构,所以只能作为数据存储 在开始这项工作之前,我需要一些经历过这场斗争的人的专家建议C# 哪个最适合数据存储结构/类?,c#,class,struct,C#,Class,Struct,我们在SO中看到了很多关于c#中类与结构的讨论。大多数结论是,这是一个堆/堆栈内存分配。并建议在小数据结构中使用structs 现在,我有一个情况来决定这两个选择中的简单数据存储。目前,在我们的应用程序中,我们有数千个类,只是充当简单的数据存储(仅公开的公共字段),它们在不同的模块和服务之间传递 根据我的理解,出于性能方面的考虑,我觉得最好还是使用struct而不是类。因为这些都是简单的数据结构,所以只能作为数据存储 在开始这项工作之前,我需要一些经历过这场斗争的人的专家建议 我的理解正确吗
- 我的理解正确吗
- 我看到大多数orm都有类作为数据存储。因此,我怀疑是否有理由继续使用类而不是结构。那会是什么
编辑:对于您描述的案例,结构将不起作用 关于结构不可变的评论是正确的。这就是它可以咬你的地方。您可以使用字段设置器定义结构,但当您更改字段值时,将创建一个新实例。因此,如果保留对旧对象的引用,它仍将引用旧值。出于这个原因,我不喜欢使用可变语句,因为这会产生微妙而复杂的bug(特别是如果使用复杂的复合语句)
另一方面,使用具有不可变状态的类也有很多很好的理由(想想字符串)。我会根据以下标准做出选择
- 引用类型与值类型语义。如果两个对象只有在它们是相同对象时才相等,则表示引用类型语义=>class。如果其成员的值定义了相等性(例如,如果两个DateTimes表示相同的时间点,即使它们是两个不同的对象,则两个DateTimes是相等的),则值类型语义=>struct
- 对象的内存占用。如果对象很大并且经常被分配,那么将其作为结构将更快地消耗堆栈,因此我宁愿将其作为类。相反,我宁愿避免对小值类型的GC惩罚;因此,使它们成为一个结构
- 你能使对象不可变吗?我发现结构非常适合“值对象”——来自DDD书籍
- 您是否会因为使用此对象而面临拳击拆箱处罚?如果是,就去上课
其主要含义是,一旦您的数据类型中有了字符串,就可以不用思考就将其作为类。否则,结构不应该容纳太多。我认为您的想法是正确的。结构用于模拟数据类型。它们是价值驱动的,而不是基于参考的。如果您查看大多数基本数据类(int、double、decimal等)的MSDN文档,它们都是基于结构的。尽管如此,结构不应该因为同样的原因被过度使用。存储该结构中所有内容的空间在实例化后立即分配,其中as类只分配空间用于引用其中的所有内容。如果数据在足够小的块中,而这不是问题,那么结构就是解决方法。如果这是一个问题,就去上课。如果您不知道,最好还是坚持您熟悉的内容。类对象的优点是可以传递对它的引用,如果引用到达外部代码,则此类引用的范围和生存期是无限的。结构的优点是,虽然可以传递对它们的短期引用,但不可能传递永久的混杂引用。这有助于避免担心是否存在此类引用 有些人建议可变的数据持有者不应该是结构。我完全不同意。在许多情况下,为了保存数据而存在的实体应该是结构化的,特别是当它们是可变的时。Eric Lippert多次发布他认为可变值类型是邪恶的(在标记“mutable”和“struct”下搜索)。确实,.net允许使用不应该使用的可变结构完成某些事情,也不方便使用它应该使用的某些事情,但是POD(“普通旧数据”)结构没有变异方法,而是通过公共字段公开其整个状态,它们的行为具有非常有用的一致性,这是任何其他数据类型都无法共享的。使用POD结构可能会使不熟悉其工作方式的人感到困惑,但会使程序变得复杂 [employeeInfoStruct is a struct containing the following field] public Decimal YearlyBonus; [someEmployeeContainer is an instance of a class which includes the following method] EmployeeInfoStruct GetEmployeeInfo(String id); // Just the signature--code is immaterial [some other method uses the following code] EmployeeInfoStruct anEmployee = someEmployeeContainer.GetEmployeeInfo("123-45-6789"); anEmployee.YearlyBonus += 100;
public struct Person
{
public DateTime Birthday { get; set; }
public int Age{ get; set; }
public String Firstname { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Person p2 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Debug.Assert(p1.Equals(p2));
Debug.Assert(p1.GetHashCode() == p2.GetHashCode());
}
}