2008-09-25 2 views
31

Каков самый гладкий способ инициализации массива динамического размера на C#, о котором вы знаете?C# Инициализация массива - с не значением по умолчанию

Это лучшее, что я мог придумать

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

    ... 

ответ

0

непроверенная, но могли бы вы сделать это?

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

Пропуск «новой части bool []»?

+1

только если IPagedResult: IEnumerable 2008-09-26 00:52:10

5

Я бы на самом деле предположить, что это:

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; 
+1

Или даже новый BOOL [кол ] .Выберите (x => true) .ToArray() – BjartN 2011-01-27 07:07:30

+2

Это все равно выделит два массива. – 2011-02-03 05:18:36

13

EDIT: как комментатор отметил, мое первоначальное осуществление не работает. Эта версия работает, но довольно негладкая, основанная на цикле 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 методы расширения серии и серии в целом.

+0

Я не верю, что ваши SetAllValues ​​будут работать: в выражении лямбда x не передается по ссылке, поэтому присвоение ему значения не изменяет значения, хранящиеся в массиве. – 2009-05-06 11:46:30

+0

Да, ты абсолютно прав. Я упомянул, что на самом деле я не скомпилировал его, что бы выявило эту довольно элементарную ошибку. Я заменил ForEach на простой цикл, и это отлично работает, но это не так, как требовал опросчик. – 2009-05-06 12:53:24

70

Если под 'сликовым' вы имеете в виду быстрый, я боюсь, что Enumerable.Repeat может быть 20x медленнее, чем для цикла. См http://dotnetperls.com/initialize-array:

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

Так используйте SetAllValues ​​Dotnetguy в метод().

1

Много раз вы хотите, чтобы инициализировать различные клетки с различными значениями:

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; 
} 
Смежные вопросы