Объяснение ArrayList - PullRequest
       15

Объяснение ArrayList

0 голосов
/ 08 января 2012

У меня есть вопрос об ArrayList (C #), и я думаю, что знаю ответ, но мне нужно подтверждение.Я хотел бы прочную основу знаний.

Так вот мой вопрос: я смотрел на пример ArrayLists и наткнулся на эту строку кода:

for (int i=1; i<=items.Count; i++)
{Console.WriteLine("{0}. {1}", i, (String)items[i-1]);}  

Вот то, что я думаюЯ знаю, что происходит.

  1. цикл for выполняется для каждого элемента в ArrayList.
  2. Выполненный код является вызовом метода Консоли WriteLine с формальным параметром.
  3. {0} будет заменено текущим значением i в цикле for, а {1} будет заменено значением в индексе ArrayList [i - 1].
  4. theпричина для [i - 1] заключается в том, что индекс ArrayList начинается с 0, а не с 1.

Вот в чем я не уверен.1. (String) << это, я полагаю, приведение значения в текущем индексе ArrayList к типу String?2. Какой тип элемента ArrayList?Это просто тип объекта? </p>

Эта концепция немного туманна для меня, и я просто ищу немного ясности.Спасибо за любую помощь вы можете сэкономить.

Ответы [ 7 ]

3 голосов
/ 08 января 2012

Массивы и списки индексируются 0 в C #. Это означает, что первый элемент имеет индекс 0, а последний элемент - индекс items.Count - 1. Я думаю, ваш код был бы более понятным, если бы цикл for начинался с 0:

for (int i = 0; i < items.Count; i++)
{
    Console.WriteLine("{0}. {1}", i + 1, (string)items[i]);
} 

Индексатор ArrayList имеет тип возврата object, поэтому, если ваш список содержит строки, вы обычно захотите привести их к строке при извлечении объекта из ArrayList. Однако в этом конкретном случае нет необходимости выполнять приведение, поскольку перегрузка WriteLine , которую вы вызываете, имеет подпись void WriteLine(string, object, object). Хорошо просто передать object этому методу. Внутренне метод WriteLine вызовет ToString для вашего объекта.

Вам также следует рассмотреть возможность использования общего класса List<T> вместо ArrayList. Класс ArrayList был полезен при первом выпуске .NET, но новый код в .NET 2.0 или выше должен использовать List<T>.

2 голосов
/ 08 января 2012

Концепция немного туманная, потому что этот цикл выполняется нестандартным способом.Идиоматический способ циклического перебора массива / списка в C # состоит в том, чтобы сделать это с начальным индексом 0

for (int i = 0; i < items.Conut; i++) {
  String current = (String)items[i];
  Console.WriteLine("{0}. {1}", i + 1, current);
}

Кажется немного неправдоподобным, чтобы код печатал индекс элемента + 1, хотя(что делает код).Первоначальный автор этого кода, похоже, больше знаком с массивами, которые индексируются начиная с 1, а не с CLR / C #, начиная с 0.

0 голосов
/ 08 января 2012

Я постараюсь дать строгое объяснение

  1. цикл for выполняется для каждого элемента в ArrayList.

Цикл продолжает выполняться, пока условие i <= items.Count остается истинным. </p>

  1. Выполненный код является вызовом метода Консоли WriteLine с формальным параметром.

Формальный параметр - это тот, который вы объявляете в сигнатуре метода. Параметр, который вы передаете методу, называется фактическим параметром.

  1. {0} будет заменено текущим значением i в цикле for, а {1} будет заменено 4. значением в индексе ArrayList [i - 1].

{0} и {1} будут заменены значением вызова ToString () параметров, которые передаются во второй и третьей позиции Console.Writeline

причина [i - 1] в том, что индекс ArrayList начинается с 0, а не с 1.

правый

Вот в чем я не уверен. 1. (String) << это, я полагаю, приведение значения в текущем индексе ArrayList к типу String? </p>

Вы правы. Это кастинг. Кроме того, это приведение не является обязательным (Console.Writeline вызывает ToString () для своих аргументов). Это вызовет InvalidCastException, если элемент в массиве имеет тип, отличный от String.

  1. Какой тип элемента ArrayList? Это просто тип объекта?

правый

0 голосов
/ 08 января 2012
  1. да, это приведение к строке отдельного элемента в ссылке на массив с помощью i-1. это предполагает, что каждый элемент в массиве является строкой. в противном случае будет выдано неверное исключение. если какие-либо элементы имеют значение null, будет выдано исключение nullreference. Я думаю, что вы задаете вопрос из-за неуверенности в приоритетности операций. без знания приоритета вы можете запутаться в том, что вы преобразуете элемент в массиве массивов в строку или сам массив (который может вызвать недопустимое исключение, если бы вы попытались это сделать). как упоминалось ранее, в этом случае это не нужно, поскольку tostring будет вызываться console.writeline.

  2. да, arraylist - это список объектов. как упоминалось ранее, дженерики предоставляют возможность иметь списки более специфических типов элементов.

тоже ничего не стоит, запуск цикла с индексом 1 неудобен. Обычно жизнь лучше, если вы начинаете с 0 и используете <для продолжения цикла, а не <=. еще лучше, если вам не нужен сам индекс, это использовать цикл foreach. </p>

0 голосов
/ 08 января 2012

Ваш анализ верен.

.NET Framework 1.0 и 1.1 не имели обобщений.Из-за этого ArrayList датируется этим временем, есть предметы типа object.Начиная с .NET 2.0 доступен универсальный List<T>, что делает старый ArrayList устаревшим в большинстве случаев.

Определите свой список как

var items = new List<string>();

Затем вы можете отбросить кастинг.

0 голосов
/ 08 января 2012

В отличие от списка, в котором мы определяем тип объектов в списке, списки массивов не являются обобщенными.

Оказывается, что внутренне ArrayList использует массив типа object для хранения своих значений. В нашем коде мы должны обрабатывать его значения, как если бы мы объявили List<object>.

Таким образом, поскольку тип не определен после object, мы должны привести наши значения, если мы хотим определить их как подкласс object (т.е. String в этом случае), потому что в противном случае компилятор будет обрабатывать его как тип object, и мы не сможем выполнить String операции.


Примечание: в этом случае приведение может быть необязательным, поскольку метод ToString() объекта будет вызываться неявно, но если мы хотим выполнить другие операции String (т.е. Substring), нам фактически потребуется приведение .

0 голосов
/ 08 января 2012
  1. (String) << это, я полагаю, приведение значения в текущем индексе ArrayList к типу String?</li>

(Строка) - это приведение, это правильно.Согласно этому приведению, да, ArrayList должен содержать любой объект типа String, в противном случае будет classcastexception.

  1. Какого типа элемент ArrayList?Это просто тип объекта?

Тип массива должен быть объектом String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...