DeV*_*Vil 152 .net c# arrays initialization
我正在忙着用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++;
}
Run Code Online (Sandbox Code Playgroud)
这很好,但我确信必须有一个更简单的方法来做到这一点.当数组UserCode = new byte[6]在构造函数中设置为时,字节数组会自动初始化为默认的空值.是否有办法让它在声明时变成所有空格,所以当我调用我的类'构造函数时,它会像这样直接初始化?或者memset类似功能?
Luk*_*keH 182
对于小型数组,使用数组初始化语法:
var sevenItems = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
Run Code Online (Sandbox Code Playgroud)
对于较大的阵列,使用标准for循环.这是最可读和最有效的方法:
var sevenThousandItems = new byte[7000];
for (int i = 0; i < sevenThousandItems.Length; i++)
{
sevenThousandItems[i] = 0x20;
}
Run Code Online (Sandbox Code Playgroud)
当然,如果你需要做很多事情,那么你可以创建一个帮助方法来帮助保持你的代码简洁:
byte[] sevenItems = CreateSpecialByteArray(7);
byte[] sevenThousandItems = CreateSpecialByteArray(7000);
// ...
public static byte[] CreateSpecialByteArray(int length)
{
var arr = new byte[length];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = 0x20;
}
return arr;
}
Run Code Online (Sandbox Code Playgroud)
Tho*_*mar 91
用它来创建数组:
byte[] array = Enumerable.Repeat((byte)0x20, <number of elements>).ToArray();
Run Code Online (Sandbox Code Playgroud)
替换<number of elements>为所需的阵列大小.
Yoc*_*mer 31
你可以使用Enumerable.Repeat()
初始化为0x20的100个项目的数组:
byte[] arr1 = Enumerable.Repeat(0x20,100).ToArray();
Run Code Online (Sandbox Code Playgroud)
Yur*_*kiy 30
var array = Encoding.ASCII.GetBytes(new string(' ', 100));
Run Code Online (Sandbox Code Playgroud)
如果需要初始化一个小数组,可以使用:
byte[] smallArray = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
Run Code Online (Sandbox Code Playgroud)
如果你有一个更大的数组,那么你可以使用:
byte[] bitBiggerArray Enumerable.Repeat(0x20, 7000).ToArray();
Run Code Online (Sandbox Code Playgroud)
这很简单,也很容易让下一个男/女孩阅读.并且99.9%的时间足够快.(通常是BestOption™)
但是,如果你真的需要超级速度,那么使用P/invoke调用优化的memset方法是适合你的:(这里包含在一个很好用的类中)
public static class Superfast
{
[DllImport("msvcrt.dll",
EntryPoint = "memset",
CallingConvention = CallingConvention.Cdecl,
SetLastError = false)]
private static extern IntPtr MemSet(IntPtr dest, int c, int count);
//If you need super speed, calling out to M$ memset optimized method using P/invoke
public static byte[] InitByteArray(byte fillWith, int size)
{
byte[] arrayBytes = new byte[size];
GCHandle gch = GCHandle.Alloc(arrayBytes, GCHandleType.Pinned);
MemSet(gch.AddrOfPinnedObject(), fillWith, arrayBytes.Length);
return arrayBytes;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
byte[] oneofManyBigArrays = Superfast.InitByteArray(0x20,700000);
Run Code Online (Sandbox Code Playgroud)
在我之前的人已经给了你答案。我只想指出你对 foreach 循环的误用。看,由于您必须增加索引标准,“for 循环”不仅更紧凑,而且效率更高(“foreach”在幕后做了很多事情):
for (int index = 0; index < UserCode.Length; ++index)
{
UserCode[index] = 0x20;
}
Run Code Online (Sandbox Code Playgroud)
这是标记为答案的帖子中代码的更快版本。
我执行的所有基准测试都表明,一个只包含数组填充之类的简单for 循环,如果它是递减的,那么它的速度通常是递增的两倍。
此外,数组 Length 属性已经作为参数传递,因此不需要从数组属性中检索它。它还应该预先计算并分配给局部变量。涉及属性访问器的循环边界计算将在每次循环迭代之前重新计算边界值。
public static byte[] CreateSpecialByteArray(int length)
{
byte[] array = new byte[length];
int len = length - 1;
for (int i = len; i >= 0; i--)
{
array[i] = 0x20;
}
return array;
}
Run Code Online (Sandbox Code Playgroud)