C# · 12月 26, 2021

C# – 如何确保我的所有结构都已初始化?

我正在用C#编写一个应用程序,它将进行大量计算.一切都围绕着基本的结构 – 价值.它基本上是一些附加参数(精度等)的两倍
它必须是一个结构体,因为会创建太多的结构来提供堆分配.
现在,我需要确保它们都已正确初始化.
我不能声明默认的显式构造函数,虽然我提供了默认构造函数,它使用0初始化所有内容,这在我的域中没有意义.

并且没有办法拒绝创建一个实例而不用参数调用我的构造函数…?

基本上我需要的是这个测试通过:

[Test]public void HowDoesThisStructureInitializeByDefault(){ Value v = new Value(); – if this did not compile – it would have been ok! Assert.AreEqual(0,v.Val); – passes Assert.AreEqual(-1,v.Accuracy); – fails}

如果没有显式调用构造函数并且仍然访问结构,则抛出异常是可以的,但是检查所有时间都需要花费太多时间.

我现在几乎失去了希望,请帮忙!

解决方法 为什么不能定义显式构造函数?这就是他们的目的.
而且,为什么你认为你“买不起堆分配”?堆栈分配在托管语言中非常便宜.您是如何测试这种假设您无法负担堆分配,或者实际上堆分配首先是更昂贵的?

(对于由“一个双参数和几个参数”组成的类型,我怀疑你的大小在哪里,堆分配实际上更便宜,效率更高)

在任何情况下,如果他愿意,你不能阻止用户调用值类型的默认构造函数.您所能做的就是确保存在初始化值的更好方法,例如非默认构造函数,或者由于某种原因无法创建一个值,在调用时创建和初始化值类型的函数.

但是,当然,你无法保证人们真正称之为它.

编辑:
.NET中的堆分配基本上只包含一个简单的堆栈推送操作.这是托管(和垃圾收集)语言的好处.运行时本质上使用一个大堆栈作为其堆,因此每个分配只是稍微增加堆栈指针(当然,在检查有足够的可用内存之后).
然后垃圾收集器在必要时负责压缩存储器.

所以堆分配本身就是非常便宜的.当然,额外的GC压力可能会再次降低你的速度(虽然据我所知,GC通过所需的时间仅取决于活动对象的数量,而不取决于要进行GC操作的时间,因此无数次“死的“周围的物体可能不是一个大问题”,但另一方面,堆栈分配也不是免费的.值类型按值传递,因此每次将类型作为参数传递给函数或返回它时,都必须进行复制.我不知道你的值有多大,但是一个double是8个字节,并且考虑到你有一些额外的参数,我假设32个字节.这可能是如此之大,以至于valuetypes所需的额外复制使得它比使用堆分配时更慢.也许.

如您所见,值和引用类型都有优势.在你的情况下,我不能说哪一个更快,但如果我是你,我会非常小心地做出这种假设.如果可能,请构造代码,以便在reference-和valuetype实现之间切换,看看哪种方法效果最好.或者,编写较小的测试以尝试预测每个测试将如何大规模执行.