我正在忙着用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类似功能?
我需要byte[]用一个非零值填充一个.如何在C#中执行此操作而不循环遍历byte数组中的每个?
更新:评论似乎将此分为两个问题 -
memset我完全同意,正如埃里克和其他人所指出的,使用一个简单的循环就可以了.问题的关键是看我是否可以学习一些关于C#的新东西:)我认为Juliet的并行操作方法应该比简单的循环更快.
基准: 感谢Mikael Svenson:http://techmikael.blogspot.com/2009/12/filling-array-with-default-value.html
事实证明,for除非你想使用不安全的代码,否则简单的循环是可行的.
抱歉我的原帖不清楚.埃里克和马克的评论都是正确的; 需要有更多专注的问题.感谢大家的建议和回应.
我已经知道下面的循环示例了
bool[] switches = new bool[20];
for (int i = 0; i < switches.Length; i++) { switches[i] = false; }
Run Code Online (Sandbox Code Playgroud)
但有没有更有效的方法将整个数组设置为false?
为了解释一下自己,我不像上面的例子那样将新的bool数组设置为false,因为它本来就是假的.在我的情况下,我正在阅读大部分进程内存,在搜索模式时最多可以触发18724次.当它确定当前字节不包含模式时,它将整个bool数组设置为false以及其他一些内容然后读取下一个内存块并重新启动循环.
虽然我更多地出于好奇而问我这个问题,因为整个过程仍然需要不到一秒钟.
再次,我的问题是,是否有更好的方法将整个bool数组设置为false?
在Java中,类Arrays中大约有18个静态"填充"方法,用于为数组中的每个元素分配一个值.我正在寻找C#中的等价物以实现同样的目的,但我找不到具有相同紧凑性的任何东西:
1)ForEach,因为我理解通过值传递数组中的元素,所以我不能更改它们
2)从Enumerable重复创建一个新数组,创建一个新数组然后从数组中复制每个元素似乎是开销
3)for循环并不漂亮,我想这就是为什么Java人员开始介绍这个紧凑的符号
4)Array类中的Clear方法可以将所有内容都设置为零,但是如何将零转换为我想要的非零值?
要演示Java的语法,请考虑此代码打印数字7的三倍:
int[] iii = {1, 2, 3};
Arrays.fill(iii, 7);
for (int i : iii) {
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud) 我有一个关于Enumerable.Repeat函数的问题.
如果我有课:
class A
{
//code
}
Run Code Online (Sandbox Code Playgroud)
我将创建一个该类型对象的数组:
A [] arr = new A[50];
Run Code Online (Sandbox Code Playgroud)
接下来,我将要初始化这些对象,调用Enumerable.Repeat:
arr = Enumerable.Repeat(new A(), 50);
Run Code Online (Sandbox Code Playgroud)
这些对象在内存中是否具有相同的地址?如果我想检查他们的哈希码,例如以这种方式:
bool theSameHashCode = questions[0].GetHashCode() == questions[1].GetHashCode();
Run Code Online (Sandbox Code Playgroud)
这将返回true,如果我将更改一个对象属性,则所有其他对象也将更改它.
所以我的问题是:是否正确地初始化引用类型对象?如果没有,那么更好的方法是什么?
我在Java中使用以下语句:
Arrays.fill(mynewArray, oldArray.Length, size, -1);
Run Code Online (Sandbox Code Playgroud)
请建议等效的C#.
我使用以下方法实现了以下基准BenchmarkDotNet:
public class ForVsFillVsEnumerable
{
private bool[] data;
[Params(10, 100, 1000)]
public int N;
[GlobalSetup]
public void Setup()
{
data = new bool[N];
}
[Benchmark]
public void Fill()
{
Array.Fill(data, true);
}
[Benchmark]
public void For()
{
for (int i = 0; i < data.Length; i++)
{
data[i] = true;
}
}
[Benchmark]
public void EnumerableRepeat()
{
data = Enumerable.Repeat(true, N).ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17763.195 (1809/October2018Update/Redstone5)
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 …Run Code Online (Sandbox Code Playgroud) 我知道我不应该优化我的程序的每一个点,让我们假设我必须优化数组初始化.
所以我写的程序,比较for loop与Array.Clear
using System;
using System.Diagnostics;
namespace TestArraysClear
{
class Program
{
static void Main(string[] args)
{
int[] a = new int[100000];
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10; i++)
{
sw.Reset();
sw.Start();
for (int j = 0; j < a.Length; j++)
{
a[j] = 0;
}
sw.Stop();
Console.WriteLine("for " + sw.ElapsedTicks);
sw.Reset();
sw.Start();
Array.Clear(a, 0, a.Length);
sw.Stop();
Console.WriteLine("Array.Clear " + sw.ElapsedTicks);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我机器上的输出:
for 1166
Array.Clear 80 …Run Code Online (Sandbox Code Playgroud) 我需要初始化一个由三个点组成的数组.我想写如下,但只有三个元素.
Point P = new Point { X = 0, Y = 1 };
Point[] P = new Point[3];// <---- ?
Run Code Online (Sandbox Code Playgroud)
怎么写得正确?
c# ×9
arrays ×7
.net ×3
boolean ×1
constructor ×1
equivalent ×1
java ×1
memset ×1
performance ×1
point ×1
set ×1