Все возможные синтаксисы инициализации массива

Ответы:

779

Это текущие методы объявления и инициализации для простого массива.

string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2

Обратите внимание, что существуют другие методы получения массивов, такие как ToArray()расширения Linq IEnumerable<T>.

Также обратите внимание, что в приведенных выше объявлениях первые два можно заменить string[]слева на var(C # 3+), так как информации справа достаточно для вывода правильного типа. Третья строка должна быть записана так, как показано, поскольку одного синтаксиса инициализации массива недостаточно для удовлетворения требований компилятора. Четвертый может также использовать умозаключение. Так что, если вам нравится вся эта краткость, вышеприведенное можно записать как

var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2 
Энтони Пеграм
источник
1
Из любопытства может ли кто-нибудь объяснить, почему выражение инициализации в 3-й строке не может использоваться само по себе (например, передаваться в метод) или присваиваться varпеременной?
Ruben9922
1
@ Ruben9922: интересный вопрос. Было бы понятно, что var x = {}не работает, если инициализатор массива может дать что-то еще, кроме массивов, но я бы не знал, что это такое. Поэтому я предполагаю, что инициализатор массива - это особенность языка. Если вы используете его вместе с new List<string> {"A", "B"}ним, вы получите что- то другое.
TvdH
442

Синтаксисы создания массива в C #, которые выражениями :

new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }

В первом случае размер может быть любым неотрицательным целочисленным значением, а элементы массива инициализируются значениями по умолчанию.

Во втором случае размер должен быть постоянным, а количество заданных элементов должно совпадать. Должно быть неявное преобразование из данных элементов в данный тип элемента массива.

В третьем элемент должен быть неявно конвертируемым в тип элемента, а размер определяется из числа заданных элементов.

В четвертом тип элемента массива определяется путем вычисления наилучшего типа, если он есть, из всех заданных элементов, имеющих типы. Все элементы должны быть неявно конвертируемыми в этот тип. Размер определяется по количеству приведенных элементов. Этот синтаксис был введен в C # 3.0.

Существует также синтаксис, который может использоваться только в объявлении:

int[] x = { 10, 20, 30 };

Элементы должны быть неявно конвертируемыми в тип элемента. Размер определяется по количеству приведенных элементов.

нет единого руководства

Я отсылаю вас к спецификации C # 4.0, раздел 7.6.10.4 «Выражения создания массива».

Эрик Липперт
источник
8
@BoltClock: первый синтаксис, который вы упомянули, это «неявно типизированное выражение создания массива». Второе - это «выражение создания анонимного объекта». Вы не перечисляете два других похожих синтаксиса; это «инициализатор объекта» и «инициализатор коллекции».
Эрик Липперт
11
Не совсем C # «синтаксис», но давайте не будем забывать (мой личный фаворит) Array.CreateInstance(typeof(int), 3)!
Джеффри Л. Уитледж
17
@ Джеффри: Если мы пойдем по этому пути, это начинает глупо. Например, "1,2,3,4".split(',').
Брайан
11
Тогда для многомерных массивов, существует «вложенная» нотация нравится new int[,] { { 3, 7 }, { 103, 107 }, { 10003, 10007 }, };, и так далее для int[,,], int[,,,]...
Jeppe Стиг Нильсен
6
@ Learning-Overthinker-Confused: у вас есть две лошади. Вы хотите знать, что быстрее. Вы (1) скачете на лошадях или (2) спрашиваете в интернете незнакомца, который никогда не видел лошадей, какая из них, по его мнению, быстрее? Гони своих лошадей . Вы хотите знать, какой из них более «эффективен»? Сначала создайте измеримый стандарт эффективности; Помните, что эффективность - это стоимость, произведенная на единицу стоимости , поэтому тщательно определите свою стоимость и стоимость. Затем напишите код в обоих направлениях и измерьте его эффективность. Используйте науку, чтобы отвечать на научные вопросы, не спрашивая случайных незнакомцев о догадках.
Эрик Липперт
111

Непустые массивы

  • var data0 = new int[3]

  • var data1 = new int[3] { 1, 2, 3 }

  • var data2 = new int[] { 1, 2, 3 }

  • var data3 = new[] { 1, 2, 3 }

  • var data4 = { 1, 2, 3 }не компилируется. Используйте int[] data5 = { 1, 2, 3 }вместо этого.

Пустые массивы

  • var data6 = new int[0]
  • var data7 = new int[] { }
  • var data8 = new [] { } и int[] data9 = new [] { }не компилируются.

  • var data10 = { }не компилируется. Используйте int[] data11 = { } вместо этого.

В качестве аргумента метода

Только выражения, которые могут быть назначены с varключевым словом, могут быть переданы в качестве аргументов.

  • Foo(new int[2])
  • Foo(new int[2] { 1, 2 })
  • Foo(new int[] { 1, 2 })
  • Foo(new[] { 1, 2 })
  • Foo({ 1, 2 }) не компилируется
  • Foo(new int[0])
  • Foo(new int[] { })
  • Foo({}) не компилируется
поцелуй мою подмышку
источник
14
Было бы лучше более четко отделить неверные синтаксисы от допустимых.
jpmc26
Полны ли приведенные примеры? Есть ли другой случай?
Ориентированный на деньги программист
49
Enumerable.Repeat(String.Empty, count).ToArray()

Создает массив пустых строк, повторяемых «количество раз». В случае, если вы хотите инициализировать массив с тем же, но специальным значением элемента по умолчанию. Осторожно со ссылочными типами, все элементы будут ссылаться на один и тот же объект.

Atomosk
источник
5
Да, у var arr1 = Enumerable.Repeat(new object(), 10).ToArray();вас есть 10 ссылок на один и тот же объект. Чтобы создать 10 различных объектов, вы можете использовать var arr2 = Enumerable.Repeat(/* dummy: */ false, 10).Select(x => new object()).ToArray();или аналогичные.
Джеппе Стиг Нильсен
20
var contacts = new[]
{
    new 
    {
        Name = " Eugene Zabokritski",
        PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
    },
    new 
    {
        Name = " Hanying Feng",
        PhoneNumbers = new[] { "650-555-0199" }
    }
};
Нахид Камалли
источник
Как вы должны использовать эту структуру? Это как словарь?
Р. Навега
1
@ R.Navega это обычный массив :)
grooveplex
17

В случае, если вы хотите инициализировать фиксированный массив предварительно инициализированных равных (не nullотличных от default) элементов, используйте это:

var array = Enumerable.Repeat(string.Empty, 37).ToArray();

Также, пожалуйста, примите участие в этой дискуссии.

Шимми Вайцхандлер
источник
13

Пример создания массива пользовательского класса

Ниже приведено определение класса.

public class DummyUser
{
    public string email { get; set; }
    public string language { get; set; }
}

Вот как вы можете инициализировать массив:

private DummyUser[] arrDummyUser = new DummyUser[]
{
    new DummyUser{
       email = "abc.xyz@email.com",
       language = "English"
    },
    new DummyUser{
       email = "def@email.com",
       language = "Spanish"
    }
};
Amol
источник
7

Повторите без LINQ :

float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);
Ник шалимов
источник
6
int[] array = new int[4]; 
array[0] = 10;
array[1] = 20;
array[2] = 30;

или

string[] week = new string[] {"Sunday","Monday","Tuesday"};

или

string[] array = { "Sunday" , "Monday" };

и в многомерном массиве

    Dim i, j As Integer
    Dim strArr(1, 2) As String

    strArr(0, 0) = "First (0,0)"
    strArr(0, 1) = "Second (0,1)"

    strArr(1, 0) = "Third (1,0)"
    strArr(1, 1) = "Fourth (1,1)"
Брэд Ларсон
источник
5
Привет, последний блок примеров, кажется, Visual Basic, вопрос требует примеров C #.
Алекс КейСмит
4
For Class initialization:
var page1 = new Class1();
var page2 = new Class2();
var pages = new UIViewController[] { page1, page2 };
Санджай Шривастава
источник
2

Еще один способ создания и инициализации массива объектов. Это похоже на пример, который @Amol опубликовал выше , за исключением того, что он использует конструкторы. Я не мог устоять перед каплей полиморфизма.

IUser[] userArray = new IUser[]
{
    new DummyUser("abc@cde.edu", "Gibberish"),
    new SmartyUser("pga@lna.it", "Italian", "Engineer")
};

Классы для контекста:

interface IUser
{
    string EMail { get; }       // immutable, so get only an no set
    string Language { get; }
}

public class DummyUser : IUser
{
    public DummyUser(string email, string language)
    {
        m_email = email;
        m_language = language;
    }

    private string m_email;
    public string EMail
    {
        get { return m_email; }
    }

    private string m_language;
    public string Language
    {
        get { return m_language; }
    }
}

public class SmartyUser : IUser
{
    public SmartyUser(string email, string language, string occupation)
    {
        m_email = email;
        m_language = language;
        m_occupation = occupation;
    }

    private string m_email;
    public string EMail
    {
        get { return m_email; }
    }

    private string m_language;
    public string Language
    {
        get { return m_language; }
    }

    private string m_occupation;
}
Ник Алексеев
источник
1

Для класса ниже:

public class Page
{

    private string data;

    public Page()
    {
    }

    public Page(string data)
    {
        this.Data = data;
    }

    public string Data
    {
        get
        {
            return this.data;
        }
        set
        {
            this.data = value;
        }
    }
}

Вы можете инициализировать массив вышеуказанного объекта, как показано ниже.

Pages = new Page[] { new Page("a string") };

Надеюсь это поможет.

PMH
источник
0

Вы также можете создавать динамические массивы, т.е. вы можете сначала запросить размер массива у пользователя, прежде чем создавать его.

Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());

int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
     dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}

Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
    Console.WriteLine(i);
}
Console.ReadKey();
Pushpendra7974
источник
0

Тривиальное решение с выражениями. Обратите внимание, что с NewArrayInit вы можете создать только одномерный массив.

NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback
unsafePtr
источник
0

Просто записка

Следующие массивы:

string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };

Будет скомпилировано в:

string[] array = new string[2];
string[] array2 = new string[]
{
   "A",
   "B"
};
string[] array3 = new string[]
{
   "A",
   "B"
};
string[] array4 = new string[]
{
   "A",
   "B"
};
Юша Алеауб
источник