Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Методы индексаторов  (Прочитано 14530 раз)
0 Пользователей и 1 Гость смотрят эту тему.
MasterMan342
Участник

ru
Offline Offline
Пол: Мужской

« : 27-05-2012 10:57 » 

Доброе время суток уважаемые формучане)
Вопрос мой таков:
есть класс Sample, в нем определен индексатор, по которому мы можем получать
доступ к коллекции.

Код:
class Sample
{
    List<int> arr = new List<int>();
    
    public int this[int val]
   {
       get
       {
           if (array.Count > val)
             return array[val];
           else return -1;//Элемента нету
       }
      
       set { ... }
   }



   public void Method() {...}
   ...
}

public static void Main()
{
     Sample g = new Sample();
     g[0] = 2;
     g[1] = 3;
     g[1].Method(...);//Проблема собственно в этом
}

Вопрос: как прикрепить метод Method к конкретному члену индексатора? (грубо говоря: мне нужно чтобы можно было вызывать метод к выделенному индексатором элементу а не к самой переменной g)

Язык - C#
« Последнее редактирование: 27-05-2012 11:07 от MasterMan342 » Записан
kotomart
Интересующийся

ru
Offline Offline

« Ответ #1 : 27-05-2012 11:10 » 

В общем, суть вашей проблемы примерно следующая: выражение g имеет тип int. Соответственно, вы пытаетесь вызвать метод Method класса int, у которого, скорее всего, его нет. Обычно в таких случаях методу Method передается в качестве параметра индекс или итератор (энумератор в терминологии C#, если я ничего не путаю) нужного элемента, или пишется класс, наследованный от вам нужного, но уже с имеющимся методом, но это в случае, если такой поступок действительно оправдан.

Добавлено через 10 минут и 48 секунд:
Имелось в виду выражение
Код:
g[i]
имеет тип int.
Мда, давно я не пользовался форумами. Уж и забыл, как это.
« Последнее редактирование: 27-05-2012 11:21 от kotomart » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 27-05-2012 11:48 » 

MasterMan342, выше объяснение правильное. По индексу получается элемент, только потом у него вызывается метод. Если нужно вызвать метод коллекции применительно к элементу, то:
Код: (C#)
g.Method(i, ...);
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
MasterMan342
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 27-05-2012 11:49 » 

Имелось в виду выражение
Код:
g[i]
имеет тип int.
Мда, давно я не пользовался форумами. Уж и забыл, как это.

Спасибо за подсказку, я вас отлично понял Улыбаюсь но как первый вариант создать новый тип, произвольный от интеджера - я еще не очень хорошо понимаю как можно создавать переменные типа классов или структур... здесь возникает проблема с преобразованием типов... можно ли как-то добавить новый метод к существующему классу или структуре? (например втереть метод Method в класс int)

Добавлено через 6 минут и 39 секунд:
MasterMan342, выше объяснение правильное. По индексу получается элемент, только потом у него вызывается метод. Если нужно вызвать метод коллекции применительно к элементу, то:
Код: (C#)
g.Method(i, ...);

я бы мог указывать индекс в параметре метода, но мне это не интересно)) я хочу понять как можно реализовать такой подход - а именно обращение к своим методам для каждого члена индексатора Улыбаюсь это просто дело принципа XD
« Последнее редактирование: 27-05-2012 11:56 от MasterMan342 » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 27-05-2012 14:23 » 

MasterMan342, твоей проблемы не существует в природе, ты ломишься в открытую дверь. Описать методы в классах, объекты которых хранятся в коллекции, тривиально.

Цитата: Козьма Прутков
Усердие всё превозмогает!

Бывает, что усердие превозмогает и рассудок.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
kotomart
Интересующийся

ru
Offline Offline

« Ответ #5 : 27-05-2012 20:49 » 

MasterMan342, на эту тему лучше почитать какую-нибудь книжку по C#, например - Герберта Шилдта. Не читал его кнуижку по C#, но вот по С++ - была моя первая книжка, и она была весьма информативна.

Касательно того, что вы хотите - могу описать кратко. Вам нужно унаследовать класс от класса int (предполагаю, что Си# должен бы позволить наследовать класс от встроенного типа), добавить в него необходимый метод, и далее использовать уже List объектов этого класса, а не int'ов. Но, подчеркиваю, такой подход стоит применять только в тех случаях, когда это оправданно с архитектурной точки зрения. Например, когда Method(); как некоторое абстрактное действие над данными является именно действием не над объектом (как элементом списка), а над объектом (как отдельно взятым представителем класса).
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 27-05-2012 21:14 » 

Цитата: kotomart
предполагаю, что Си# должен бы позволить наследовать класс от встроенного типа
Для встроенного int есть класс Int32.

Только это бессмыслица, поскольку никакой прикладной задачи не решается. Проще создать собственный класс, чем пытаться наследовать int. Результат будет одинаковый.

Цитата: kotomart
когда это оправданно с архитектурной точки зрения. Например, когда Method(); как некоторое абстрактное действие над данными является именно действием не над объектом (как элементом списка), а над объектом (как отдельно взятым представителем класса).
Вот тут у него и основная путаница. Фактически он хочет подменить семантику выражения x[i].y(). Он хочет, чтобы оператор [] возвращал элемент по индексу, но чтобы при этом оператор . относился не к результату работы оператора [], а к самому x. Эта затея заведомо обречена на провал, поскольку является попыткой перехитрить язык программирования. Можно создать оператор [], возвращающий сам объект-коллекцию, и тогда можно будет записать такое выражение. Но при этом оператор [] лишится возможности возвращать элементы. А внутри класса-коллекции придётся заводить поле, которое в начале сохранит аргумент оператора [], а затем из вызванного метода можно будет воспользоваться значением такого индекса. Мало того, что это громоздко по сравнению с аргументом в методе, так оно ещё и заведомо не thread-safe.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
kotomart
Интересующийся

ru
Offline Offline

« Ответ #7 : 27-05-2012 21:33 » 

..., но чтобы при этом оператор . относился не к результату работы оператора [], а к самому x

Ой, бес попутал. Почему-то стал думать, что MasterMan342 хочет вызывать метод элемента списка, а не класса-коллекции. Да, тогда код еще более странный, надо кардинально менять его, так дела не делаются.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 27-05-2012 22:11 » 

Вам нужно унаследовать класс от класса int (предполагаю, что Си# должен бы позволить наследовать класс от встроенного типа), добавить в него необходимый метод, и далее использовать уже List объектов этого класса, а не int'ов.

В языке C# ключевое слово int соответствует 32-битному знаковому целому, имеет семантику значения (а не ссылки, как большинство библиотечных объектов), и поэтому реализуется структурой (а не классом) System.Int32, входящей в состав Common Type System среды .NET.
В C# (в отличие, например, от того же C++, где классы и структуры - фактически синонимы), структуры существенно отличаются от классов. Как я упомянул выше, они имеют семантику значения; кроме того, они не могут наследовать от других классов/структур (хотя могут реализовывать интерфейсы), и от них самих наследование также не допускается.
Итак, поскольку int в C# - фактически структура, сама идея наследовать от int несостоятельна, и все основанные на ней дальнейшие рассуждения не имеют смысла.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
kotomart
Интересующийся

ru
Offline Offline

« Ответ #9 : 27-05-2012 22:19 » 

Dale, о, интересно. Знаком с C# только понаслышке, так что и сам сомневался в том, что можно наследовать от инта. Хотя, конечно, это слегка неожиданное поведение такого языка. Кстати, был у меня вопрос относительно другого аспекта поведения языка C#, которое было как минимум странным. Задам его, пожалуй, в отдельной теме.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 27-05-2012 22:31 » 

...это слегка неожиданное поведение такого языка.

Мне оно представляется вполне логичным. Поскольку ссылки на структуры отсутствуют, то и полиморфизм работать не будет. А если нет полиморфизма, то и польза от наследования сомнительна.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
kotomart
Интересующийся

ru
Offline Offline

« Ответ #11 : 27-05-2012 22:52 » 

Для меня неожиданно то, что int в C# не класс, но не более того. Скажем так, я не этого ожидал от этого языка, но если int в C# не является классом - то да, далее все логично и очевидно. Кстати, если не сложно, не могли бы прокомментировать еще один момент, который мне кажется непривычным?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 28-05-2012 07:33 » 

kotomart, если зачем-то хочется унаследовать целое число (или работать с самим числом как с объектом) - для этого в C# есть набор IntXX и UIntXX-классов(Int32, например). А базовые типы - они для эффективности.

ЗЫ. Извиняюсь, был неправ - Int32 унаследовать, похоже, не получится. Видимо, язык всё по тем же соображениям эффективности ограничили в возможностях наследования: value class унаследовать нельзя. Что не отменяет наличия самого такого типа Улыбаюсь
« Последнее редактирование: 28-05-2012 07:38 от Вад » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 28-05-2012 07:42 » 

Нет в C# таких классов. Есть встроенный тип int, который реализован библиотечной структурой System.Int32 из CTS.NET.

Впрочем, это мы уже по второму кругу поехали: https://forum.shelek.ru/index.php/topic,28662.msg280341.html#msg280341
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 28-05-2012 17:57 » new

Dale, а, прошу прощения, я это с C++.NET перепутал - там для аналога C#-структур есть специальная разновидность классов. Код попутал и комменты выше не прочитал  Скромно так...
« Последнее редактирование: 28-05-2012 17:59 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines