Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как по "умному" переписать класс 
V
    Опции темы
Ch0bits
Дата 26.3.2006, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 9
Всего: 62



Код

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

namespace ConsoleApplication1
{
    /// <summary>
    /// Позволяет хранить произвольные объекты и получать к ним доступ по имени
    /// </summary>
    public class SceneObjectsCollection
    {
        ArrayList Objects = new ArrayList();
        List<string> Names = new List<string>();

        /// <summary>
        /// Пихает объект в кучу
        /// </summary>
        /// <param name="Obj">Объект</param>
        /// <param name="Name">Имя</param>
        public bool Add(object Obj, string Name)
        {
            if (Names.IndexOf(Name) == -1)
            {
                Objects.Add(Obj);
                Names.Add(Name);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Получаем доступ к объекту по индексу
        /// </summary>
        /// <param name="Index">Индекс</param>
        public object this[int Index]
        {
            get
            {
                return Objects[Index];
            }
            set
            {
                Objects[Index] = value;
            }
        }

        /// <summary>
        /// Получаем доступ к объекту по имени
        /// </summary>
        /// <param name="Name">Назначенное объекту имя</param>
        /// <returns></returns>
        public object this[string Name]
        {
            get
            {
                int i = Names.IndexOf(Name);
                return Objects[i];
            }
            set
            {
                int i = Names.IndexOf(Name);
                Objects[i] = value;
            }
        }

        /// <summary>
        /// Удаляет объект из коллекции по индексу
        /// </summary>
        /// <param name="Index">Индекс</param>
        /// <returns>true - удачное удаление</returns>
        public bool Delete(int Index)
        {
            try
            {
                Names.RemoveAt(Index);
                Objects.RemoveAt(Index);
            }
            catch
            {
                return false; // Не удалось удалить объект
            }
            return true;
        }

        /// <summary>
        /// Удаляет объект из коллекции по имени
        /// </summary>
        /// <param name="Name"></param>
        /// <returns>true - удачное удаление</returns>
        public bool Delete(string Name)
        {
            try
            {
                int i = Names.IndexOf(Name);
                Names.RemoveAt(i);
                Objects.RemoveAt(i);
            }
            catch
            {
                return false;
            }
            return true;
        }

        public int Count
        {
            get { return Objects.Count; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SceneObjectsCollection S = new SceneObjectsCollection();
            S.Add("Hello World!", "1");
            S.Add("2 + 2 = 7", "2");
            S.Add("Vingrad rulezzz!", "3");
            
            // Доступ по индексу
            for(int i=0;i<S.Count;i++)
            {
                 Console.WriteLine(S[i] as string);
            }

            // Доступ по имени
            Console.WriteLine(S["3"] as string);

            Console.ReadKey();
        }
    }
}


Вот такая штука: осуществляет доступ к объектам по имени (имена не должны совпадать).
Как бы это привести к человеческому виду и чтобы можно было через foreach получать элементы? А то наворотил я тут... smile
smile
PM WWW   Вверх
Void
Дата 26.3.2006, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Ch0bits, тебе обязательно нужен доступ по индексу? Если нет, то все что тебе нужно — это System.Collections.Generic.Dictionary<string, object>.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Ch0bits
Дата 26.3.2006, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 9
Всего: 62



Цитата(Void @ 26.3.2006, 21:17 Найти цитируемый пост)
тебе обязательно нужен доступ по индексу?

Да.
PM WWW   Вверх
Void
Дата 26.3.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Цитата(Ch0bits @ 26.3.2006, 23:41 Найти цитируемый пост)
тебе обязательно нужен доступ по индексу?

Да.

Рискну все-таки уточнить. Если индекс тебе нужен только для перебора всех объектов, то все равно можно обойтись Dictionary, потому что он реализует IEnumerable. Если же нужен именно индекс, можно сделать примерно так: завести маппинг строковых имен на индексы плюс индексируемый список или массив объектов. Чтобы обеспечить быстрое удаление по индексу, вместе с объектами в списке будем держать их имена. Если объекты удаляются нечасто, а оверхед по памяти критичен, можно этого и не делать.
Код

class IndexedDictionary<T> : IEnumerable<T>
{

    private class NameValuePair
    {
        public string name;
        public T value;

        public NameValuePair(string name, T value)
        {
            this.name = name;
            this.value = value;
        }
    }

    private IDictionary<string, int> entries_;
    private IList<NameValuePair> items_;

    public IndexedDictionary()
    {
        entries_ = new Dictionary<string, int>();
        items_ = new List<NameValuePair>();
    }

    public bool Add(string name, T item)
    {
        if (entries_.ContainsKey(name))
            return false;
        entries_[name] = items_.Count;
        items_.Add(new NameValuePair(name, item));
        return true;
    }

    public T this[int index]
    {
        get
        {
            return items_[index].value;
        }
        set
        {
            items_[index].value = value;
        }
    }

    public T this[string name]
    {
        get
        {
            return items_[entries_[name]].value;
        }
        set
        {
            items_[entries_[name]] = new NameValuePair(name, value);
        }
    }

    public bool Delete(int index)
    {
        try
        {
            string name = items_[index].name;
            items_.RemoveAt(index);
            entries_.Remove(name);
        }
        catch
        {
            return false;
        }
        return true;
    }

    public bool Delete(string name)
    {
        try
        {
            int index = entries_[name];
            items_.RemoveAt(index);
            entries_.Remove(name);
        }
        catch (KeyNotFoundException e)
        {
            return false;
        }
        return true;
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach (NameValuePair pair in items_)
            yield return pair.value;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        foreach (NameValuePair pair in items_)
            yield return pair.value;
    }

}


Это сообщение отредактировал(а) Void - 26.3.2006, 22:36


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Ch0bits
Дата 26.3.2006, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 9
Всего: 62



Void
Круто пишешь. smile

Цитата(Void @ 26.3.2006, 22:34 Найти цитируемый пост)
нужен именно индекс

Да. Мне там всё нужно.

Вот сам прилепил работу с foreach.
Код

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

namespace ConsoleApplication1
{
    /// <summary>
    /// Позволяет хранить произвольные объекты и получать к ним доступ по имени
    /// </summary>
    public class SceneObjectsCollection : IEnumerable

    {
        ArrayList Objects = new ArrayList();
        List<string> Names = new List<string>();

        /// <summary>
        /// Пихает объект в кучу
        /// </summary>
        /// <param name="Obj">Объект</param>
        /// <param name="Name">Имя</param>
        public bool Add(object Obj, string Name)
        {
            if (Names.IndexOf(Name) == -1)
            {
                Objects.Add(Obj);
                Names.Add(Name);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Получаем доступ к объекту по индексу
        /// </summary>
        /// <param name="Index">Индекс</param>
        public object this[int Index]
        {
            get { return Objects[Index]; }
            set { Objects[Index] = value; }
        }

        /// <summary>
        /// Получаем доступ к объекту по имени
        /// </summary>
        /// <param name="Name">Назначенное объекту имя</param>
        public object this[string Name]
        {
            get
            {
                int i = Names.IndexOf(Name);
                return Objects[i];
            }
            set
            {
                int i = Names.IndexOf(Name);
                Objects[i] = value;
            }
        }

        /// <summary>
        /// Удаляет объект из коллекции по индексу
        /// </summary>
        /// <param name="Index">Индекс</param>
        /// <returns>true - удачное удаление</returns>
        public bool Delete(int Index)
        {
            try
            {
                Names.RemoveAt(Index);
                Objects.RemoveAt(Index);
            }
            catch
            {
                return false; // Не удалось удалить объект
            }
            return true;
        }

        /// <summary>
        /// Удаляет объект из коллекции по имени
        /// </summary>
        /// <param name="Name">Имя объекта</param>
        /// <returns>true - удачное удаление</returns>
        public bool Delete(string Name)
        {
            try
            {
                int i = Names.IndexOf(Name);
                Names.RemoveAt(i);
                Objects.RemoveAt(i);
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Возвращает количество элементов
        /// </summary>
        public int Count
        {
            get { return Objects.Count; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Enumerator(this);
        }

        /// <summary>
        /// Внутренний класс-перечислитель
        /// </summary>
        private class Enumerator : IEnumerator
        {
            private SceneObjectsCollection soc;

            public Enumerator(SceneObjectsCollection soc)
            {
                this.soc = soc;
            }

            private int pos = -1;

            public object Current
            {
                get { return soc.Objects[pos]; }
            }

            public bool MoveNext()
            {
                if (pos < soc.Objects.Count-1)
                {
                    pos++;
                    return true;
                }
                else
                    return false;
            }

            public void Reset()
            {
                pos = -1;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SceneObjectsCollection S = new SceneObjectsCollection();
            S.Add("Hello World!", "1");
            S.Add("good morning!", "2");
            S.Add("Vingrad rulezzz", "3");
            S.Add("string", "123");

            S["123"] = "AAAAAA";
            S[0] = S[0] + " And " + S[1];

            // Перерь работает!
            foreach(object o in S)
                Console.WriteLine(o as string);

            Console.ReadKey();
        }
    }
}


PM WWW   Вверх
Void
Дата 26.3.2006, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Цитата(Ch0bits @ 27.3.2006, 00:48 Найти цитируемый пост)
Вот сам прилепил работу с foreach.

Если ты пишешь на .NET 2.0, то эти извраты с ручным созданием IEnumerator ни к чему — пользуйся yield.
Добавлено @ 22:57
Чем мой вариант-то не устроил? Доступ по имени у тебя будет сильно тормозить на большом количестве объектов.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Ch0bits
Дата 26.3.2006, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 9
Всего: 62



Void
Аааа! Какой ты умный! smile Почему я не могу писать так-же как ты? smile


Цитата(Void @ 26.3.2006, 22:56 Найти цитируемый пост)
пользуйся yield

А чего это?
Добавлено @ 22:59
Цитата(Void @ 26.3.2006, 22:56 Найти цитируемый пост)
Чем мой вариант-то не устроил?

Я теперь им пользуюсь. smile
PM WWW   Вверх
Void
Дата 26.3.2006, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Цитата(Ch0bits @ 27.3.2006, 00:57 Найти цитируемый пост)
пользуйся yield

А чего это?

См. MSDN.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1125 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.