这个问题在这里已有答案:
我正在忙于将用C语言完成的旧项目重写为C# .
我的任务是重写程序,使其尽可能接近原始程序 .
在一堆文件处理过程中,编写该程序的前一个开发人员创建了一个包含大量字段的结构,这些字段对应于必须写入文件的设置格式,因此所有这些工作都已经完成 .
这些字段都是字节数组 . 然后C代码使用 memset
将整个结构设置为所有空格字符( 0x20
) . 一行代码 . 简单 .
这非常重要,因为此文件最终使用的实用程序是期望此格式的文件 . 我必须要做的是将此结构更改为C#中的类,但我找不到一种方法可以轻松地将每个字节数组初始化为所有空格字符 .
我最终要做的是在类构造函数中:
//Initialize all of the variables to spaces.
int index = 0;
foreach (byte b in UserCode)
{
UserCode[index] = 0x20;
index++;
}
这很好,但我确信必须有一个更简单的方法来做到这一点 . 当数组在构造函数中设置为 UserCode = new byte[6]
时,字节数组会自动初始化为默认的空值 . 我是否有办法让它在声明时变成所有空格,所以当我调用我的类'构造函数时,它会像这样直接初始化?还是一些 memset
般的功能?
13 回答
对于小型数组,使用数组初始化语法:
对于较大的阵列,使用标准的
for
循环 . 这是最可读和最有效的方法:当然,如果你需要做很多事情,那么你可以创建一个帮助方法来帮助保持你的代码简洁:
使用它来首先创建数组:
将
<number of elements>
替换为所需的数组大小 .你可以用Enumerable.Repeat()
100个项目的数组初始化为0x20:
如果需要初始化一个小数组,可以使用:
如果你有一个更大的数组,那么你可以使用:
这很简单,也很容易让下一个男/女孩阅读 . 并且99.9%的时间足够快 . (通常是BestOption™)
但是,如果你真的需要超高速,那么使用P / invoke调用优化的memset方法是适合你的:(这里包含了一个很好用的类)
用法:
也许这些可能会有所帮助?
What is the equivalent of memset in C#?
http://techmikael.blogspot.com/2009/12/filling-array-with-default-value.html
我之前的伙伴们给了你答案 . 我只是想指出你滥用foreach循环 . 看,因为你必须增加索引标准“for loop”不仅更紧凑,而且更高效(“foreach”做了很多事情):
最快的方法是使用api:
bR = 0xFF;
RtlFillMemory(pBuffer,nFileLen,bR);
使用指向缓冲区的指针,写入的长度和编码的字节 . 我认为在托管代码中执行它的最快方法(慢得多)是创建一小块初始化字节,然后使用Buffer.Blockcopy将它们写入循环中的字节数组 . 我把它扔到一起但没有测试过,但是你明白了:
只是为了扩展我的答案,一个更简洁的方式多次这样做可能是:
哪个叫:
这有一个很好的循环效率(提到gwiazdorrr的答案)以及如果它被大量使用的漂亮整洁的调用 . 与我个人认为的枚举相比,一瞥可读 . :)
您可以使用collection initializer:
如果值不相同,这将比_820142更好 .
此函数比填充数组的for循环更快 .
Array.Copy命令是一种非常快速的内存复制功能 . 此函数通过重复调用Array.Copy命令并将我们复制的内容加倍,直到数组已满为止 .
我在我的博客上讨论了这个问题http://coding.grax.com/2013/06/fast-array-fill-function-revisited.html
请注意,通过在方法声明中添加单词"this",即
public static void ArrayFill<T>(this T[] arrayToFill ...
,这很容易变成扩展方法这是标记为答案的帖子的更快版本的代码 .
我所执行的所有基准测试表明,只有包含类似数组填充的简单for循环,如果递减则通常是两倍,而不是递增 .
此外,数组Length属性已作为参数传递,因此无需从数组属性中检索它 . 它也应该预先计算并分配给局部变量 . 涉及属性访问器的循环边界计算将在循环的每次迭代之前重新计算边界的值 .
您可以使用Parallel类(.NET 4和更高版本)加速初始化并简化代码:
当然你可以创造数组同时: