Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > эррэй лист


Автор: kettle 17.6.2008, 23:14
Здравствуйте!

можно ли для разных объектов класса запись производить в один и тот же массив?
т.е. например у меня есть класс Пр, хочу написать скажем Пр1.Эррэй_лист.Эдд Пр2.Эррэй_лист.Эдд и так далее?)

наверное, мой вопрос совсем дурацкий))

Автор: mihryak 18.6.2008, 00:36
вот так можно - через статическое поле, оно шарится между всеми экземплярами этого класса
Код

        public class Pr
        {
            private static readonly ArrayList arrayList = new ArrayList();

            public ArrayList ArrayList
            {
                get { return arrayList; }
            }
        }

но в этом что-то есть несимпатичное (имею в виду не общий статический список, а постановку задачи)
зачем это понадобилось?

Автор: Certain 5.7.2008, 02:27
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Pr pr = new Pr();
            Pr pr1 = new Pr();
            string str = "dsgfdsg";
            int i = 3;
            double dbl = 3.2;
            char ch='a';
            pr.Add(str);
            pr.Add(i);
            pr1.Add(dbl);
            pr1.Add(ch);
            Console.WriteLine("Количество элементов массива = {0}",pr.Count.ToString());
            Console.WriteLine("тип pr[0] = string? {0}", (pr[0] is string) ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[0] = char? {0}", (pr[0] is char) ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[1] = int? {0}", pr[1] is int ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[1] = char? {0}", pr[1] is char ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[2] = double? {0}", pr[2] is double ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[2] = int? {0}", pr[2] is int ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[3] = char? {0}", pr[3] is char ? "ДА" : "НЕТ");
            Console.WriteLine("тип pr[3] = int? {0}", pr[3] is int ? "ДА" : "НЕТ");
            Console.ReadLine();
        }
    }
    public class Pr
    {
        private static ArrayList _arrayList;
        public Pr()
        {
            _arrayList = new ArrayList();
        }
        public void Add(object obj)
        {
            _arrayList.Add(obj);
        }
        public object this[int index]
        {
            get { return _arrayList[index]; }
            set { _arrayList[index] = value; }
        }
        public int Count
        {
            get { return _arrayList.Count; }
        }
    }
}

 smile 
Уважаемый mihryak, поле readonly инициализировать можно только в реализации коструктора класса, статические readonly соответственно только в статичесих конструкторах, так что это не вариант...

Автор: Partizan 5.7.2008, 09:46
Certain, 
Код

Уважаемый mihryak, поле readonly инициализировать можно только в реализации коструктора класса


Вы ошибаетесь.

Автор: Certain 5.7.2008, 12:47
Partizan ,  smile 

Автор: Partizan 5.7.2008, 14:49
Certain, 
Код

    public class Test
    {
        public static readonly ArrayList arr = new ArrayList();
        public Test()
        {
            
        }
    }


Код

    public class Test
    {
        public readonly ArrayList arr = new ArrayList();
        public Test()
        {
            
        }
    }


посмотрите секцию Remarks по поводу ключевого слова readonly в MSDN

Автор: nikitao 7.7.2008, 11:44
Partizan,  я так понял , что вы имеете ввиду декларативную инициализацию ? Если так , то это часть конструктора , так что Certain прав.

Автор: Partizan 7.7.2008, 14:21
nikitao, Читаем внимательнее:

Цитата

mihryak:

Код

        public class Pr
        {
            private static readonly ArrayList arrayList = new ArrayList();
            public ArrayList ArrayList
            {
                get { return arrayList; }
            }
        }



Цитата

Certain:
Уважаемый mihryak, поле readonly инициализировать можно только в реализации коструктора класса, статические readonly соответственно только в статичесих конструкторах, так что это не вариант...


Во-первых я показал, что поле readonly инициализировать можно не только в реализации коструктора класса
Во-вторых я показал, что статические readonly инициализировать можно и без реализации статического конструктора

Автор: PashaPash 7.7.2008, 15:23
Цитата(Partizan @  7.7.2008,  14:21 Найти цитируемый пост)

Во-первых я показал, что поле readonly инициализировать можно не только в реализации коструктора класса
Во-вторых я показал, что статические readonly инициализировать можно и без реализации статического конструктора 
Вообще-то inline-инициализация - это часть реализации конструктора. Возьми код, откомпилируй, и ковырни рефлектором
Код
public class Pr
{
    private static readonly ArrayList arrayList = new ArrayList();
    public ArrayList ArrayList
    {
        get { return arrayList; }
    }

    private static readonly ArrayList arrayList2;

    static Pr()
    {
        arrayList2 = new ArrayList();
    }
}

получилось:
Код
static Pr()
{
    arrayList = new ArrayList();
    arrayList2 = new ArrayList();
    return;
}
Так что ничего ты не показал.

Автор: mihryak 7.7.2008, 15:49
а о чём спор-то вообще идёт? о том, какой код во что транслится, или о том, можно ли инициализировать readonly не в конструкторах?
если второй пункт - то люлбой, имеющий компиллятор, может проверить и получить однозначный ответ.

Автор: Partizan 7.7.2008, 15:51
PashaPash, во что код превращается - это другая тема...прочитайте топик с самого начала...
в ответ на код mihryak, который вполне валиден и имеет право на существование, Certain возразил что "поле readonly инициализировать можно только в реализации коструктора класса"...хотя фактически это не так... опять повторюсь, что с тем что компилятор встраивает инициализацию в конструктор внутри я ни капли не спорю...

я всего-лишь понял пост Certain-а как отрицающий валидность кода приведённого mihryak-ом...

Автор: PashaPash 7.7.2008, 16:06
Partizan, inline-инициализация - это часть конструктора с точки зрения CLR, и часть объявления поля с точки зрения C#. Так что все правы понемногу.
А по теме - за public ArrayList надо громко ругать.

Автор: nikitao 7.7.2008, 18:14
Согласен с  PashaPash. Я об этом и говорил.

Автор: Partizan 7.7.2008, 19:02
nikitao, Зато Certain явно говорил о другом )

Автор: nikitao 7.7.2008, 19:48
Ладно. Все поняли , что все друг друга поняли smile  Где аффтор то ?

Автор: wotker 7.7.2008, 19:51
Главное что не поругались! =) 
Автор уже давно походу не следит за темой

Автор: Certain 9.7.2008, 22:27
В догонку  smile 
Начнем, пожалуй, с задачи
Цитата

можно ли для разных объектов класса запись производить в один и тот же массив?
т.е. например у меня есть класс Пр, хочу написать скажем Пр1.Эррэй_лист.Эдд Пр2.Эррэй_лист.Эдд и так далее?)


Тут все четко сказано! Нужно использовать много (как минимум 2) экземпляров одного, в данном случае Pr, класса! И при этом, где-то при использовании в коде, чтобы можно было добавить элемент в массив экземпляра класса, удалить или изменить!

Теперь к дискуссии:
Уважаемый Partizan
Я не писал, что код 
Код

 public class Pr
        {
            private static readonly ArrayList arrayList = new ArrayList();

            public ArrayList ArrayList
            {
                get { return arrayList; }
            }
        }
 
неправильный, я только сказал, что это "не вариант" для решения данной задачи (прошу не путать)

По поводу примера "инициализации" Partizanа
Код

public class Test
    {
        public static readonly ArrayList arr = new ArrayList();
        public Test()
        {
            
        }
    }

строка public static readonly ArrayList arr = new ArrayList(); это всего лишь объявление экземпляра класса ArrayList! 
Да, не спорю, при этом инициализируются все поля этого класса в null или 0! Но при использовании такого класса, зачем мне нулевой массив, как я буду его использовать в своем коде, какие операции я могу с ним производить(добавить , удалить, изменить)?! - НИКАК! Речь идет про инициализацию элементов массива, объявленного как поле readonly! Как не крути, инициализировать элементы (в данном случае) массива  readonly Вы сможите только 
-в конструкторе класса,
-в методе класса, опять же, передав этом массив как параметр метода! Этот метод должен вызываться только из конструктора,
-или, воспользовавшись новшеством языка C# 3.0 - автореализуемые поля, пример привести не могу, т.к. нет под рукой студии 2008(последнее я утверждать не могу, не проверял, но судя по документации можно инициализировать свойства "только для чтения", соответственно, я предполагаю,что и readonly можно инициализировать аналогичным путем)

ввел в поисковик поля readonly в C# и из первой же найденой статьи:
Цитата

...
Переменные поля readonly имеют большую гибкость, нежели const, потому что позволяют перед присваиванием производить различные вычисления значения, которое должно быть "только для чтения". Правило использования таких полей говорит, что вы можете присваивать им значение только в конструкторе, и нигде более. Одной из основных особенностей таких полей, является то, что они могут пренадлежать и экземплярам класса, а не быть статическими. Это позволяет получать различные значения полей только для чтения в разных экземплярах классов. Это значит, что в отличие от полей const, если вы хотите сделать поле readonly статическим, то должны явно обьявить его таковым.
...

Помоему кто-то кого-то не правильно понял....  smile 
Вобщем, к данной задаче использовать такие поля не вариант!

Автор: mihryak 9.7.2008, 22:42
Цитата(Certain @  9.7.2008,  23:27 Найти цитируемый пост)
Как не крути, инициализировать элементы (в данном случае) массива  readonly Вы сможите только 
-в конструкторе класса,
-в методе класса, опять же, передав этом массив как параметр метода! Этот метод должен вызываться только из конструктора,

чушь, простите =)
строка 
Код

private static readonly ArrayList arrayList = new ArrayList();

производит полноценные создание и инициализацию списка
работать с таким созданным экземпляром можно как угодно и где угодно - как внутри класса в любом методе, как и вынеся его наружу (хреновость второго метода оставим за кадром)

явный конструктор тут вовсе необязателен

и в цитате приведённой ниже тоже чушь написана, так бывает =)

пс. перед такими трактатами стоило всё же мой код запустить и убедиться в 
- синтаксической правильности
- работоспособности
- удовлетворении поставленных требований (про хреновость такой реализации здесь пишу третий раз)

добавление
кажется, понял причину недопонимания Certain'а - она в неправильном понимании инициализации
на самом деле, инициализация в данном контексте - лишь присваивание значения, она действительно возможно только при объявлении поля и в конструкторе
а работа с объектом, который, собственно, был присвоен этому полю в дальшейшем доступна любая, предоставляемая его интерфейсом
т.е. заполнение дефолтовыми значениями, прочие добавления/удаления и т.п. - это вовсе не инициализация, а работа с уже готовым с использованию объектом

Автор: Certain 9.7.2008, 23:17
 
Цитата
A readonly field can be initialized either at the declaration or in a constructor. 
Readonly fields can have different values depending on the constructor used.

 smile 
http://msdn.microsoft.com/en-us/library/acdd6hb7(VS.80).aspx

Добавления!
Поповоду ссылочных типов, ты прав.... потому что в поле readonly записывается только ссылка на объект, соответственно её изменять нельзя, а с самим объектом можно делать все что угодно.... да точно! Я говорил про поля readonly значимых типов, не учел, что массивы к сылочным типам относятся...  smile 
Твои объяснения меня только путают...  smile 

трактат выдал  smile 
Нельзя просто написать, что все эти правила для readonly относятся только к значимым типам, с сылочными изменять можно в объекте все, кроме ссылки на объект, воды много  smile 

Автор: mihryak 9.7.2008, 23:35
Цитата
A readonly field can be initialized either at the declaration or in a constructor. 
Readonly fields can have different values depending on the constructor used.

переводим
Цитата

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

то же самое пишет и msdn в Вашей же ссылке
Цитата

You can assign a value to a readonly field only in the following contexts:
      When the variable is initialized in the declaration


Цитата(Certain @  10.7.2008,  00:17 Найти цитируемый пост)
А теперь прочитай внимательно задачу, что требуется smile ему не нужен фиксированный массив остоянны величин....

хотите сказать, что код
Код

            Pr pr1 = new Pr();
            pr1.ArrayList.Add("1");
            Pr pr2 = new Pr();
            pr2.ArrayList.Add("2");

            foreach (object obj in pr1.ArrayList)
            {
                Console.WriteLine(obj.ToString());
            }

            foreach (object obj in pr2.ArrayList)
            {
                Console.WriteLine(obj.ToString());
            }

не будет работать или выдаст разные списки? ну-ну
неужели не возникло сомнение в своей правоте и не заставило написать тестик на проверку?

Автор: Certain 9.7.2008, 23:39
см. выше, обновил уже давно

Вопрос: Для чего в этой задаче применять поле readonly? Смысл?

Автор: Partizan 9.7.2008, 23:50
Certain, 
mihryak, 

чесно, даже добавлять ничего не хочется ))) аффтар уже давно получил решение задачи, а истина была установлена =)

Автор: Certain 9.7.2008, 23:57
Да, я тоже так думаю, давайте закроем эту тему!
Уважаемый mihryak, признаю Вашу правоту! Разобрались, на разные темы рассуждали, да и я не все учел!
Давайте жить дружно, мне Ваша помощь ещё понадобиться!  smile 

Автор: nikitao 9.7.2008, 23:58
Все тут неосилил, но последний пост мне понравился. УРА!

Автор: mihryak 10.7.2008, 00:05
мир-труд-май =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)