.net C#数组初始化-使用非默认值

vohkndzv  于 2023-03-24  发布在  .NET
关注(0)|答案(7)|浏览(172)

在C#中初始化一个动态大小的数组的最巧妙的方法是什么?
这是我能想到的最好的了

private bool[] GetPageNumbersToLink(IPagedResult result)
{
   if (result.TotalPages <= 9)
      return new bool[result.TotalPages + 1].Select(b => true).ToArray();

   ...
wqlqzqxt

wqlqzqxt1#

如果你说的“slickest”是指最快的话,恐怕Enumerable.Repeat可能比for循环慢20倍。参见http://dotnetperls.com/initialize-array

Initialize with for loop:             85 ms  [much faster]
Initialize with Enumerable.Repeat:  1645 ms

所以使用Dotnetguy的SetAllValues()方法。

ogq8wdun

ogq8wdun2#

使用Enumerable.Repeat

Enumerable.Repeat(true, result.TotalPages + 1).ToArray()
kpbwa7wx

kpbwa7wx3#

  • 编辑:正如一位评论者指出的,我最初的实现不起作用。这个版本可以工作,但基于for循环的不太灵活。*

如果您愿意创建一个扩展方法,您可以尝试这样做

public static T[] SetAllValues<T>(this T[] array, T value) where T : struct
{
    for (int i = 0; i < array.Length; i++)
        array[i] = value;

    return array;
}

然后像这样调用它

bool[] tenTrueBoolsInAnArray = new bool[10].SetAllValues(true);

作为一种选择,如果你喜欢有一个类在周围,你可以尝试这样的东西

public static class ArrayOf<T>
{
    public static T[] Create(int size, T initialValue)
    {
        T[] array = (T[])Array.CreateInstance(typeof(T), size);
        for (int i = 0; i < array.Length; i++)
            array[i] = initialValue;
        return array;
    }
}

你可以像这样调用

bool[] tenTrueBoolsInAnArray = ArrayOf<bool>.Create(10, true);

不知道我更喜欢哪一个,虽然我做lurv扩展方法很多很多。

rlcwz9us

rlcwz9us4#

实际上,我会这样建议:

return Enumerable.Range(0, count).Select(x => true).ToArray();

这样你只分配一个数组。这本质上是一种更简洁的表达方式:

var array = new bool[count];

for(var i = 0; i < count; i++) {
   array[i] = true;
}

return array;
lyfkaqu1

lyfkaqu15#

很多时候,你想用不同的值初始化不同的单元格:

public static void Init<T>(this T[] arr, Func<int, T> factory)
{
    for (int i = 0; i < arr.Length; i++)
    {
        arr[i] = factory(i);
    }
}

或者在工厂的味道:

public static T[] GenerateInitializedArray<T>(int size, Func<int, T> factory)
{
    var arr = new T[size];
    for (int i = 0; i < arr.Length; i++)
    {
        arr[i] = factory(i);
    }
    return arr;
}
qcbq4gxm

qcbq4gxm6#

未经测试,但你能做这个吗?

return result.Select(p => true).ToArray();

跳过“new bool[]”部分?

wtlkbnrh

wtlkbnrh7#

在写这个答案的时候,所有的答案都忽略了.NET为此明确提供的功能,调用,我引用.NET代码注解,他们为所有大小不是1字节的类型提供的“优化的主力方法”。如果它的大小只有一个字节,那么memset将被内在地调用。
如果你对它的工作原理感兴趣,workhorse方法涉及到向量化和循环展开的组合,以将所有元素设置在一个保证连续的内存区域中,跨度为给定值。保证允许进一步的构建和JIT优化。要将这个过程向量化,有四个约束:
1.该体系结构必须支持SIMD指令,
1.类型不能是或包含引用,
1.类型的大小不得大于字节向量中的通道数量,
1.类型的大小必须是2的幂。
要利用这一点,您只需要调用Array.Fill或span的Fill方法。下面是一个示例:

var a = new bool[1_000];
Array.Fill(a, true); // Same as: a.AsSpan().Fill(true);
Console.WriteLine(String.Join(", ", a));

相关问题