Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象或可空类型作为结构中的字段有什么含义(如果有的话)_C#_.net_Struct - Fatal编程技术网

C# 将对象或可空类型作为结构中的字段有什么含义(如果有的话)

C# 将对象或可空类型作为结构中的字段有什么含义(如果有的话),c#,.net,struct,C#,.net,Struct,出于性能原因,我在几个用例中使用结构 如果我在另一个结构中有一个对象或一个可为null的类型,但作为结构中的一个成员可以为null,是否会对性能产生不利影响。我是否失去了我试图获得的利益 编辑 我知道结构的大小限制和正确使用。请不要再讲课了。在性能测试中,结构执行得更快 我的意思并不是说我的话听起来粗鲁或忘恩负义,但我该如何使我的问题变得更简单呢 将对象作为结构的成员是否会影响性能或否定此好处?不,您不一定会失去此好处。当您在一个循环中快速创建许多对象并且不需要将这些对象传递给任何其他方法时,您

出于性能原因,我在几个用例中使用结构

如果我在另一个结构中有一个对象或一个可为null的类型,但作为结构中的一个成员可以为null,是否会对性能产生不利影响。我是否失去了我试图获得的利益

编辑

我知道结构的大小限制和正确使用。请不要再讲课了。在性能测试中,结构执行得更快

我的意思并不是说我的话听起来粗鲁或忘恩负义,但我该如何使我的问题变得更简单呢


将对象作为结构的成员是否会影响性能或否定此好处?

不,您不一定会失去此好处。当您在一个循环中快速创建许多对象并且不需要将这些对象传递给任何其他方法时,您可以看到使用结构带来的性能好处。在这种情况下,您应该很好,但如果没有看到一些代码,就无法判断。

就我个人而言,我更担心的是不恰当地使用结构;你所描述的听起来像是一个对象类

特别是,我会担心你的结构太大;当您在变量之间、方法之间等传递结构时,它会被复制。如果它是一个有很多字段的大型野兽,其中一些字段本身就是野兽,那么这个副本将占用堆栈上更多的空间和更多的CPU时间。与向对象传递引用不同,对象的大小/时间宽度根据x86/x64体系结构是恒定的

如果我们谈论基本的可空类型,比如经典值;Nullable当然有开销;真正的问题是:

太多了吗 这比我还得为一个神奇的数字等做的支票贵吗 特别是,Nullable上的所有强制转换和运算符都会获得额外的代码,例如:

int? a = ..., b = ...;
int? c = a + b;
实际上更类似于:

int? c = (a.HasValue && b.HasValue) ?
              new Nullable<int>(a.GetValueOrDefault() + b.GetValueOrDefault())
            : new Nullable<int>();

要想知道这是否太多,唯一的办法是使用您自己的本地测试和数据。在这种情况下,数据位于结构上这一事实在很大程度上是没有意义的;无论数字在哪里,它们都应该进行广泛的比较。

好吧,当涉及到结构与类的性能部分时,C是一个奇怪的野兽

检查此链接:

根据微软的说法,只有当实例大小小于16字节时,才应该使用struct。安德鲁是对的。如果不传递结构,可能会看到性能优势。值类型语义有很高的性能和时间内存,这取决于您在传递它们时所做的事情

就集合而言,如果您使用的是非泛型集合,则在这种情况下,值类型结构的装箱和拆箱将比引用类型(即类)具有更高的性能开销。也就是说,结构的分配速度确实比类快

虽然struct和class具有相同的语法,但行为却大不相同。这可能会迫使您产生许多难以跟踪的错误。例如,当您调用结构中的公共隐藏构造函数时,不会调用结构中的like静态构造函数,或者as运算符在使用结构时会失败

可以为空的类型本身是由结构实现的。但他们确实有处罚。即使是每一个可为null类型的操作也会发出更多的IL

好吧,在我看来,struct可以在DateTime或guid等类型中使用。如果需要不可变类型,请使用struct,否则不要使用。性能优势并没有那么大。同样,即使是开销也没有那么大。因此,归根结底,它取决于您存储在结构中的数据以及您如何使用它。

Nullable本质上是一个T和bool标志的元组,指示它是否为null。因此,它的性能效果是完全相同的:就大小而言,您可以得到额外的bool加上它认为需要的任何填充


对于引用类型的引用,没有特殊含义。它只是一个对象引用的大小,通常是sizeofintpttr,尽管我不认为有一个明确的保证。当然,GC还必须时不时地跟踪这些引用,但结构中的引用在这方面并不特别。

可空类型和不可变类类型都不会在结构中造成问题。但是,在使用可变类类型时,通常应坚持以下两种方法之一:

可变类字段或属性表示的状态应该是其引用的可变对象的*标识*,而不是*可变字符*。例如,假设一个结构有一个类型为“Car”的字段,其中包含对红色汽车的引用,车辆ID为24601。进一步假设有人复制结构,然后将车辆漆成蓝色。在这种情况下,如果希望 结构来保存对ID为24601的蓝色汽车的引用。如果希望结构仍然保留对红色汽车的引用,这将是不合适的,因为汽车ID 24601是蓝色的,因此必须具有其他ID。 结构中的代码创建一个可变类实例,对该实例执行所有可能从传入实例复制数据的变化,并在所有变化完成后将其存储在私有字段中。一旦对实例的引用存储在字段中,结构就不能再对该实例进行变异,也不能将其暴露于任何可能对其进行变异的代码中。
注意,这两种方法提供了非常不同的语义;一个人不应该很难在两者之间做出决定,因为在任何情况下,一个是合适的,另一个是完全不合适的。在某些情况下,可能会有其他更好的方法,但一般来说,应该确定结构的状态是否包括任何嵌套可变类的标识或可变特征,并根据需要使用上述模式之一。

您的问题询问了结构的性能优势,但没有提供如何使用结构的示例。这类似于你问我某辆车的性能如何,而不告诉我该车将在城市、公路、越野等处行驶。我只是要求提供一个简单的代码示例,为你的问题提供上下文。作为旁注:在未来,当向他人寻求帮助时,最好是更通融、更少磨蹭。让我解释一下,你有价值41K的代表,这使你占Jon Skeet的38%。我只是很惊讶你要求一个代码示例。相信我,加里,我可能拥有乔恩·斯基特38%的声誉,但这并不意味着我拥有他接近38%的知识或才智。我仍然不明白为什么拥有大量的堆栈溢出声誉会让我有能力读懂您的想法并提取您的用例,从而能够告诉您的结构将如何为每个用例执行。我们想帮助您,但您必须帮助我们才能做到这一点。如果没有特定的用例代码示例,我们只能提供猜测。你说我们在给你讲课,但我说,鉴于你提供的少量信息,我们正在提供最好的答案。我很抱歉,安德鲁,我是一个工具——但我很抱歉地为自己辩护,我刚刚采访了一位资深建筑师兼首席架构师,他被认为是LINQ和其他23个领域的专家。当我问他如何使用linq对整数数组求和时,他要求提供一个代码示例。你甚至不想看到他的lambda密码。再次表示歉意!