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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> struct, Чем плох 
:(
    Опции темы
Domestic Cat
Дата 19.6.2005, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Чем плоха структура - у меня это назревало давно, а после недолгой писанины под террариум совсем наболело.

1. Структуры плохи вот чем. Угадайте что выдаст этот код
Код

A a = new A();
a.X = 1;
A b = a;
a.X = 2;
Console.WriteLine(b.X.ToString());


Точно нельзя сказать, т.к. если А - это структура, то код выдаст 1, а если класс - то 2. Нет никакого различия между двумя разными сущностями - созданной на стеке и созданной на хипе. Результат - трудноуловимые баги.
Интересно о чем думали Микрософт и создатели языка... Сейчас в мире более 3,000,000 Java девелоперов. Предположим завтра на шарп перейдет 500,000... Сколько из них будут просто не замечать такие моменты? Если писал на Java , привыкаешь к тому, что для классов всегда сработает копирование ссылки, а не всего объекта...

2. Для создания структуры можно пользовать оператор new, который вообще-то предназначен для создания объектов на хипе, что вносит еще больше путаницы. Из строки
Код

A a = new A();


опять-таки невозможно понять что создано - объект или структура. Непонятно зачем так сделано, ведь можно было использовать синтаксис
Код

A a();

например.

3. Структуру можно создать двумя различными способами. Зачем? От одного (с new) можно было отказаться.

4. Утверждается что структура более оптимальна. На самом деле это не всегда так. Вот несколько примеров.
а. Я создаю структуру, содержащую много всего - массив, ссылки на объекты, и т п. Все это будет при любой операции копироваться на стеке.
б. Я кладу структуры в коллекцию, например хештейбл. Каждая структура будет boxed в объект, и при манипуляциях с коллекцией она будет проходить стадии boxed - unoxed - boxed и т п. Помимо потери производительности мы получаем также еще и кучу левых объектов, которые будет убирать сборщик.

Все это не такие уж и редкие ситуации, если учесть что структура никак не отличается от класса. Тот же Java девелопер привык, что Point - это класс. А такое использование Point может привести как к потере производительности, так и к багам... И структура в FCL не одна..
Причем никто не позаботился хотя бы о соглашении о названии структур - ну разве сложно было бы называть структуры как в С - прописными буквами? Хотя бы стандартные структуры легко было бы отличить.

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


--------------------

PM   Вверх
stab
Дата 19.6.2005, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Мдя... согласен с тобой, сам над этими вещами задумывался. Еще одна проблема, скажем, озаботился я оптимизацией и пытаюсь использовать структуры повсеместно, но с головой, конечно. Проект развивается, размеры структур растут, приходится передовать их в другие методы по ссылке (ref), т.е. как обычный объект и стоило тогда использовать структуры?! Со временем принимается решение о переводе всего кода на классы и тут возникает беда описанная тобой в п.1, старый код больше не работает, как задумывалось.

Помойму единственное для чего структуры можно реально использовать, так это какие-то специфические маленькие обертки вокруг простых типов (int, float, т.д.) в которых точно не ожидается роста числа полей.

Кстати, может кто-то обяснит, какой смысл в запрете на реализацию конструктора без параметров в структурах?


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Domestic Cat
Дата 19.6.2005, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Цитата(cully @ 19.6.2005, 01:55)
какой смысл в запрете на реализацию конструктора без параметров в структурах?


Компилятор сам создает за тебя конструктор без параметров, потому ты его не можешь объявить - получится что он два раза объявлен. А создает он его видимо для того, чтоб там присвоить всем полям значения по умолчанию.

Цитата(cully @ 19.6.2005, 01:55)
Помойму единственное для чего структуры можно реально использовать, так это какие-то специфические маленькие обертки вокруг простых типов (int, float, т.д.) в которых точно не ожидается роста числа полей.

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


--------------------

PM   Вверх
Дрон
Дата 19.6.2005, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 92



Domestic Cat
Придётся с тобой согласится smile

Я в своих прогах структуры если и использовал, то только для группировки данных, над которыми после создания никаких изменений не производится вообще.

Это сообщение отредактировал(а) Дрон - 19.6.2005, 11:42


--------------------
Да. Именно так.
PM   Вверх
stab
Дата 19.6.2005, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Цитата(Domestic @ 19.6.2005, 08:12)
Компилятор сам создает за тебя конструктор без параметров, потому ты его не можешь объявить - получится что он два раза объявлен. А создает он его видимо для того, чтоб там присвоить всем полям значения по умолчанию.


Оно и понятно, только иногда значения полей по умолчанию для структуры хочется задать отличными от нуля, приходится идти обманным путем, делать конструктор с параметром, который в нем не используется smile


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
mr.DUDA
Дата 20.6.2005, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Domestic @ 19.6.2005, 09:41)
Точно нельзя сказать, т.к. если А - это структура, то код выдаст 1, а если класс - то 2. Нет никакого различия между двумя разными сущностями - созданной на стеке и созданной на хипе. Результат - трудноуловимые баги.

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

Цитата(Domestic @ 19.6.2005, 09:41)
а. Я создаю структуру, содержащую много всего - массив, ссылки на объекты, и т п. Все это будет при любой операции копироваться на стеке.

Нет никакого смысла использовать такую структуру

Цитата(Domestic @ 19.6.2005, 09:41)
3. Структуру можно создать двумя различными способами. Зачем? От одного (с new) можно было отказаться.

С непроинициализированными value-type переменными вообще опасно иметь дело. В шарпе общепринято использовать new, будь то структура или класс.

Цитата(Domestic @ 19.6.2005, 09:41)
б. Я кладу структуры в коллекцию, например хештейбл. Каждая структура будет boxed в объект, и при манипуляциях с коллекцией она будет проходить стадии boxed - unoxed - boxed и т п. Помимо потери производительности мы получаем также еще и кучу левых объектов, которые будет убирать сборщик.

Решаемо с пом. generics.

Цитата(Domestic @ 19.6.2005, 09:41)
Тот же Java девелопер привык, что Point - это класс.

Переучится smile




--------------------
user posted image
PM MAIL WWW   Вверх
Domestic Cat
Дата 21.6.2005, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



mr.DUDA, такое впечатление будто ты из Микрософта smile
Цитата(mr @ 20.6.2005, 14:51)
Вопрос удобства и целесообразности. Обычно структура является служебной конструкцией, используемой в рамках одного класса, для того чтобы иметь возможность хранить несколько переменных (подчёркиваю, именно открытых полей) в одной обёртке, плюс конструктор для удобства

Если так, то эта структура будет обернута в класс-враппер, ведь сам то класс хранится на хипе. А это опять-таки потеря производительности. Для таких целей существуют внутренние классы.


Цитата(mr @ 20.6.2005, 14:51)
Нет никакого смысла использовать такую структуру

Смысла нет, но возможность есть. А раз она есть - ее будут использовать.


Цитата(mr @ 20.6.2005, 14:51)
С непроинициализированными value-type переменными вообще опасно иметь дело. В шарпе общепринято использовать new, будь то структура или класс.

При чем тут как принято? Речь идет о том что это возможно.


Цитата(mr @ 20.6.2005, 14:51)
Решаемо с пом. generics.

Объясни, как. ArrayList - ето объект. Если я туда ложу структуры, то листу все равно нужны ссылки на объекты на хипе.

Цитата(mr @ 20.6.2005, 14:51)
Переучится smile

smile Ну да, переучится. Но затратит на это время. И все из-за кривизны рук разработчиков.


--------------------

PM   Вверх
mr.DUDA
Дата 21.6.2005, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Domestic @ 21.6.2005, 01:00)
mr.DUDA, такое впечатление будто ты из Микрософта 

я долго смеялся... smile smile smile

Цитата(Domestic @ 21.6.2005, 01:00)
Цитата
Решаемо с пом. generics.

Объясни, как. ArrayList - ето объект. Если я туда ложу структуры, то листу все равно нужны ссылки на объекты на хипе.

Вот пример:
Код
using System;

namespace ConsoleApplication1
{
    public class SimpleList<T>
    {
        public SimpleList<T> next = null;
        public T value;

        public SimpleList(T v)
        {
            value = v;
        }

        public SimpleList<T> Add(T v)
        {
            return next = new SimpleList<T>(v);
        }
    }
    
    class Program
    {
        struct POINT
        {
            public int X;
            public int Y;
            public POINT(int x, int y) { X = x; Y = y; }
        }

        static void Main(string[] args)
        {
            POINT pt1 = new POINT(1, 1);
            POINT pt2 = new POINT(2, 2);
            POINT pt3 = new POINT(3, 3);

            SimpleList<POINT> item1 = new SimpleList<POINT>(pt1);
            SimpleList<POINT> item2 = item1.Add(pt2);
            SimpleList<POINT> item3 = item2.Add(pt3);

            for (SimpleList<POINT> item = item1; item != null; item = item.next)
                Console.WriteLine("X=", item.value.X, " Y=", item.value.Y);
        }
    }
}

Все структуры лежат на стеке. Никакого boxing-а.


--------------------
user posted image
PM MAIL WWW   Вверх
Domestic Cat
Дата 21.6.2005, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Цитата(mr @ 21.6.2005, 00:42)

Все структуры лежат на стеке. Никакого boxing-а.

Как такое возможно? Предположим мы добавили в лист 10 структур в методе А. Далее метод завершился - в таком случае выбрасывается весь фрейм, ранее принадлежавший этому методу, а вместе с нм и все структуры. Потому их и нужно хранить на хипе. И от использования генериков ничего не изменится, просто компилятор запрячет боксинг/анбоксинг в IL, а для тебя это будет выглядеть будто боксинга нет.


--------------------

PM   Вверх
mr.DUDA
Дата 21.6.2005, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Domestic @ 21.6.2005, 10:07)
Как такое возможно? Предположим мы добавили в лист 10 структур в методе А. Далее метод завершился - в таком случае выбрасывается весь фрейм, ранее принадлежавший этому методу, а вместе с нм и все структуры.

Не уверен на 100%, но по-моему понятие "стек" в дотнете слегка отличается от общепринятого. Поправьте меня, если не так.


--------------------
user posted image
PM MAIL WWW   Вверх
Domestic Cat
Дата 21.6.2005, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Суть стека в том, что это стек - скорость работы со стеком больше, чем с хипом. Потому там ничего не должно оставаться ни в коем случае.


--------------------

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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