我知道c#中实例化的值类型数组会自动填充该类型的默认值(例如bool为false, int为0,等等)。

是否有一种方法来自动填充一个不是默认的种子值的数组?无论是在创建或之后的内置方法(如Java的Arrays.fill())?假设我想要一个默认为true的布尔数组,而不是false。是否有一个内置的方法来做到这一点,或者你只需要通过一个for循环迭代数组?

 // Example pseudo-code:
 bool[] abValues = new[1000000];
 Array.Populate(abValues, true);

 // Currently how I'm handling this:
 bool[] abValues = new[1000000];
 for (int i = 0; i < 1000000; i++)
 {
     abValues[i] = true;
 }

必须遍历数组并将每个值“重置”为true似乎效率不高。还有其他方法吗?也许通过翻转所有值?

在输入这个问题并思考之后,我猜默认值只是c#在幕后处理这些对象的内存分配的结果,所以我想这可能是不可能的。但我还是想确定一下!


当前回答

这也是可行的……但可能没有必要

 bool[] abValues = new bool[1000];
 abValues = abValues.Select( n => n = true ).ToArray<bool>();

其他回答

不幸的是,我不认为有一个直接的方法,但我认为你可以为数组类写一个扩展方法来做到这一点

class Program
{
    static void Main(string[] args)
    {
        int[] arr = new int[1000];
        arr.Init(10);
        Array.ForEach(arr, Console.WriteLine);
    }
}

public static class ArrayExtensions
{
    public static void Init<T>(this T[] array, T defaultVaue)
    {
        if (array == null)
            return;
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = defaultVaue;
        }
    }
}

如果你计划只设置数组中的几个值,但大多数时候想要获得(自定义)默认值,你可以尝试这样做:

public class SparseArray<T>
{
    private Dictionary<int, T> values = new Dictionary<int, T>();

    private T defaultValue;

    public SparseArray(T defaultValue)
    {
        this.defaultValue = defaultValue;
    }

    public T this [int index]
    {
      set { values[index] = value; }
      get { return values.ContainsKey(index) ? values[index] ? defaultValue; }
    }
}

您可能需要实现其他接口以使其有用,例如在数组本身上的接口。

Boolean[] data = new Boolean[25];

new Action<Boolean[]>((p) => { BitArray seed = new BitArray(p.Length, true); seed.CopyTo(p, 0); }).Invoke(data);
Enumerable.Repeat(true, 1000000).ToArray();

并行实现怎么样

public static void InitializeArray<T>(T[] array, T value)
{
    var cores = Environment.ProcessorCount;

    ArraySegment<T>[] segments = new ArraySegment<T>[cores];

    var step = array.Length / cores;
    for (int i = 0; i < cores; i++)
    {
        segments[i] = new ArraySegment<T>(array, i * step, step);
    }
    var remaining = array.Length % cores;
    if (remaining != 0)
    {
        var lastIndex = segments.Length - 1;
        segments[lastIndex] = new ArraySegment<T>(array, lastIndex * step, array.Length - (lastIndex * step));
    }

    var initializers = new Task[cores];
    for (int i = 0; i < cores; i++)
    {
        var index = i;
        var t = new Task(() =>
        {
            var s = segments[index];
            for (int j = 0; j < s.Count; j++)
            {
                array[j + s.Offset] = value;
            }
        });
        initializers[i] = t;
        t.Start();
    }

    Task.WaitAll(initializers);
}

当只初始化一个数组时,这段代码的力量是看不出来的,但我认为你绝对应该忘记“纯”for。