当前位置: 首页 > 编程语言 > C#

C#学习教程:.NET中的空数组是否使用任何空间?分享

时间:2023-04-10 20:15:15 C#

.NET中的空数组是否使用任何空间?我有一些代码,我在其中返回一个对象数组。这是一个简化的例子:string[]GetTheStuff(){Lists=null;if(somePredicate()){s=newList();//假设我们加载了一些数据或其他东西}return(s==null)?新字符串[0]:s.ToArray();}问题是,newstring[0]有多贵?我是否应该只返回null并让调用者接受null作为指示“未找到任何内容”的有效方式?注意:这是在循环中调用的,它运行了数百次,所以这是我认为这种优化实际上“不成熟”的少数情况之一。PS:虽然现在还为时过早,但我还是想知道它是如何工作的:-)更新:最初,当我问它是否使用任何空间时,我在考虑'C/C++',有点像写作炭[5];在C中将在堆栈上分配5个字节的空间,并且charb[0];将分配0个字节。我意识到这不适合.NET世界,但我很好奇这是否是编译器或CLR会检测并优化掉的东西,因为大小为零的不可调整大小的数组真的不应该(据我所知)可以看到吗?)不需要存储空间。即使它被称为“成百上千”次,我也会说这是一个过早的优化。如果结果作为空数组更清晰,请使用它。现在给出实际答案:是的,一个空数组需要一些内存。它有正常的对象开销(我相信在x86上是8个字节),以4个字节计数。我不知道它还有什么,但它不是完全免费的。(虽然它很便宜......)幸运的是,您可以在不牺牲API本身的情况下进行优化:具有空数组的“常量”。如果你允许,我做了另一个小改动以使代码更清晰......privatestaticreadonlystring[]EmptyStringArray=newstring[0];string[]GetTheStuff(){if(somePredicate()){Lists=newList();//假设我们加载了一些数据或其他东西returns.ToArray();}else{返回EmptyStringArray;如果你经常发现自己需要这个,你甚至可以创建一个带有静态成员的泛型类来返回一个正确类型的空数组。.NET泛型的工作方式使这变得微不足道:publicstaticclassArrays{publicstaticreadonlyEmpty=newT[0];}(当然,您可以将其包装在属性中。)然后只需使用:Arrays。空的;编辑:我只记得EricLippert关于数组的帖子。您确定数组是最合适的类型吗?即将推出的.NET4.6版本(2015年晚些时候)包括一个返回零长度字符串[]的静态方法:Array.Empty()我想如果多次调用它会返回相同的实例。声明的数组总是必须包含以下信息:这可能是微不足道的,但对于更大的维度和更长的长度,它将对循环产生性能影响。至于返回类型,我同意应该返回一个空数组而不是null。更多信息:.NET中的数组类型是的,正如其他人所说,空数组占用对象的标头和长度字段的几个字节。但是,如果您担心性能,您就会担心这种方法中的错误执行分支。我更关心填充列表上的ToArray调用,这将导致内存分配等于其内部大小和列表内容的内存副本。如果你真的想提高性能,那么(如果可能的话)通过使返回类型之一直接返回列表:List、IList、ICollection、IEnumerable,具体取决于你需要它的设施(注意,通常最好少具体的)。我猜一个空数组只使用分配对象指针本身所需的空间。根据记忆,API指南说你应该总是从返回数组的方法返回一个空数组,而不是null,所以我不关心你的代码是什么样的。这样调用者就知道他一定会得到一个数组(即使是一个空数组)并且不需要在每次调用时都检查是否为null。编辑:关于返回空数组的链接:http://wesnerm.blogs.com/net_undocumented/2004/02/empty_arrays.html其他人已经很好地回答了你的问题。所以只是一个快速点......我会避免返回一个数组(除非你不能)。坚持使用IEnumerable,然后您可以使用LINQAPI中的Enumerable.Empty()。显然微软已经为你优化了这种情况。IEnumerableGetTheStuff(){列表s=null;如果(somePredicate()){varstuff=newList();//加载数据返回的东西;}返回Enumerable.Empty();这不是您问题的直接答案。了解为什么数组被认为有些危险。我建议您在这种情况下返回一个IList并重新编译代码:IListGetTheStuff(){Lists=newList();if(somePredicate()){//假设我们加载了一些数据或其他东西}returns;这样,调用者就不必关心null返回值。编辑:如果返回的列表不可编辑,您可以将列表包装在ReadOnlyCollection中。只需将最后一行更改为.我也会考虑这个最佳实践。返回新的ReadOnlyCollection(s);如果我理解正确的话,会为字符串数组分配少量内存。您的代码本质上需要创建一个通用列表,那么为什么不返回它呢?[编辑]删除了返回null的代码版本。在这种情况下建议反对空返回值的其他答案似乎是更好的建议[/编辑]ListGetTheStuff(){Lists=newList我知道这是一个老问题,但它是一个基本问题,我需要一个详细的回答。所以我对此进行了探索并得到了结果:在.Net中创建数组时(在本例中我使用int[]),在为数据分配任何内存之前需要6个字节。考虑这段代码[在32位应用程序中!]:int[]myArray=newint[0];int[]myArray2=newint[1];char[]myArray3=newchar[0];查看内存:myArray:a81a8f700000000000000000myArray2:a81a8f70010000000000000000000000myArray3:50068f700000000000让我们解释一下内存:现在我对零长度数组感觉好多了,我知道它是如何工作的=]以上是C#学习教程:.NET中的空数组是否使用任何空间?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: