-
Привет всем. Пользуетесь ли часто дженериками в разработке приложений? Не так давно захотел переделать часть проекта с использованием дженериков, ну типа модно, удобно и все такое :)
В плане создания простых рекордов и методов классов, без использования конвертирования в реальные типы - получается действительно интересно. Но вот если в методе приходится конвертировать и много дженерики в реальные типы (в том числе и внутренние переменные класса), выходит совсем неудобочитаемый код, хотя, дженерики вроде как подразумевались для упрощения жизни. Что бы было понятнее, приведу простой абстрактный пример. Есть класс и функция, которая в зависимости от типа создаваемого обьекта конвертирует параметр в строку
type
TTestClass<T> = class
public
function GetText(Param: T): string;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TTestClass<Integer>.Create do
try
Caption := GetText(1);
finally
Free;
end;
with TTestClass<Double>.Create do
try
Caption := GetText(1.1);
finally
Free;
end;
end;
function TTestClass<T>.GetText(Param: T): string;
var
Info: PTypeInfo;
Value: TValue;
begin
Result := '';
Info := System.TypeInfo(T);
Value := TValue.From<T>(Param);
case Info.Kind of
tkInteger: Result := IntToStr(Value.AsInteger);
tkFloat: Result := FloatToStr(Value.AsExtended);
end;
end;
Имхо, код GetText неудобочитаемый и вообще не сильно Object Pascal напоминает. А теперь представьте, что в реальном коде дженерики используются для сотни внутренних переменных, которые в методе надо туда-сюда конвертировать. Вот реально получается какая-то фигня. После месяца экспериментов думаю, может стоило все сделать вариантами
Кто что думает по этому поводу и насколько часто этим у себя пользуетесь?
-
Для такого простейшего случая дженерики избыточны. Нет смысла совать их во все подряд.
-
Всякий овощ приносит пользу, будучи употреблен надлежащим образом в надлежащее время, дженерики не исключение.
По теме, да, пользуюсь, но в большинстве своем имеющимися в RTL классами.
Вариант в данном примере тоже некрасив и не сопровожаем. Если переделывать проекты на новые возможности языка потому что это модно, лучше вместо этого заняться изобретением самодвижущегося пресс-папье, всяко больше пользы будет.
-
Просто надо правильно пользоваться вы применили неправильный подход.
Дженерики предназначены для обобщённое программирование. Вот вы должны были среди разных классов выделить единое для всех классов и это запихнуть в дженерик. А вы выдели разное.
Хотя, конечно бывают и исключения. Так что небольшой case на 1-2 пукнта возможен.
-
Rouse_
> Для такого простейшего случая дженерики избыточны
Это просто пример был, что бы показать суть проблемы. В реальности все сложнее. Но вот не вижу в подобных случаях никакой пользы в этом и все. Только для простых каких-то обобщенных записей интересно это смотрится. Вот и думаю - может я чего-то не так делаю
Игорь Шевченко
> Вариант в данном примере тоже некрасив
Так и я о том же. Даже простой пример с конвертированием в реальные типы получается некрасив. А в сложных методах - вообще жуть
> Если переделывать проекты на новые возможности языка потому
> что это модно
Руководство хочет :)
Pavia
> Дженерики предназначены для обобщённое программирование
Я понимаю. Понятна суть и, в общем, нравиться идея. Но впихнуть это в код старых проектов как-то не сильно пока удачно выходит
-
> Но впихнуть это в код старых проектов как-то не сильно пока
> удачно выходит
Ну вот почти все ответившие сказали что "впихнуть это" в код старых проектов по меньшей мере нецелесообразно. Так зачем тогда пытаться?
-
В дельфи - не пользуюсь практически вообще из-за недоразвитой реализации. А вот в сях - весьма активно.
-
maxsvt © (09.08.16 00:52) [4]
> Руководство хочет :)
Тогда это не вопрос для форума, не так ли ? Ну или пригласить на форум руководство, чтобы узнать его точку зрения без испорченного телефона.
-
> В дельфи - не пользуюсь практически вообще из-за недоразвитой
> реализации. А вот в сях - весьма активно.
А вот это хотелось бы обсудить. Реализация в си да и в Си# более богатая чем в Delphi. Но стоит ли переводить? Или есть технические ограничения которые припрятывают разрастанию различных коллекций?
Вообще кто нибудь сравнивал дженирики на Си или Си# с теми что в Delphi?
-
> maxsvt © (09.08.16 00:52) [4]
Понятно. Я обычно дженерики для хранения структур использую с последующей сортировкой - очень удобно получается (ну как один из вариантов)
-
> Вообще кто нибудь сравнивал дженирики на Си или Си# с теми
> что в Delphi?
А чего там сравнивать?
Достоинства дженериков дельфи = пересечение достоинств дженериков C# и шаблонов С++
Недостатки дженериков дельфи = объединение недостатков дженериков С# и шаблонов С++
Раздувают бинарный код как шаблоны. Возможностей меньше чем в шарпе.
-
> Достоинства дженериков дельфи = пересечение достоинств дженериков
> C# и шаблонов С++
> Недостатки дженериков дельфи = объединение недостатков дженериков
> С# и шаблонов С++
Самому руки не дойдут, посмотреть.
В том то и дело что там отличия существенные. Нет множественного наследования. Поэтому в ряде коллекций внутри дженерика приходится добавлять ещё дженерик.
TList<T> = class(TEnumerable<T>)
...
type {Тип в типе}
TEnumerator = class(TEnumerator<T>)
private
FList: TList<T>;
FIndex: Integer;
function GetCurrent: T;
protected
function DoGetCurrent: T; override;
function DoMoveNext: Boolean; override;
public
constructor Create(const AList: TList<T>);
property Current: T read GetCurrent;
function MoveNext: Boolean;
end;
function GetEnumerator: TEnumerator; reintroduce;
end;
Притом таких типов как TEnumerator - с одним названием в юните объявлена целая куча.
Отсюда ущербность.
-
> Отсюда ущербность.
Чья ? Развелось ламеров, плюнуть некуда, всяко в ламера попадешь.
-
> Вообще кто нибудь сравнивал дженирики на Си или Си# с теми
> что в Delphi?
Чтобы не переходить в крайности, то это как сталь и алюминий.
Взять хотя бы вот это:
В С++ шаблоном может функция. В Дельфи - только метод, если хочешь функцию городи класс. Вопрос: А [зачем]?
В С++ я спокойно могу написать такое
template <class T> CTemplate
}
Почему я не могу написать в Дельфи
TGeneric<T> = class
public
function Get: T;
end;
function TGeneric<T>.Get: T;
var
R: T;
begin
R = T.Create;
R.AddRef();
Result := R;
end;
Другими словами шаблон в C++ это не более чем продвинутая директива препроцессора, а что такое дженерик в Delphi?
-
Было бы прикольно если бы можно было примерно так:
function TTestClass<T>.GetText(Param: T): string;
begin
Result := SomeToStr(Param);
end;
где:
function SomeToStr(A: String): String; overload;
function SomeToStr(A: Integer): String; overload;
function SomeToStr(A: Double): String; overload;
-
C++ ждёт тебя
-
Германн
> Так зачем тогда пытаться
Была мысль, что что-то это упростит. Когда появилась сама идея
-
DayGaykin - ну так обьявите
function SomeToStr(A: String): String; overload;
function SomeToStr(A: Integer): String; overload;
function SomeToStr(A: Double): String; overload
внутри класса
-
> maxsvt © (11.08.16 00:38) [16]
>
> Германн
>
> > Так зачем тогда пытаться
>
> Была мысль, что что-то это упростит. Когда появилась сама
> идея
>
Создание новых проектов это действительно может упростить. Но не обязательно. А вот перевод старых проектов на дженерики вряд ли что-то упростит.
-
> А вот перевод старых проектов на дженерики вряд ли что-то
> упростит.
Аргументы последуют ?
-
Серега, конечно, слегка перегнул, но приведу аргументы для ИШ :)
Работает - не трожь :)
-
> Rouse_ © (11.08.16 14:23) [20]
Безусловно - это главный аргумент. :)
-
Ждёмс аргументы от противной стороны. :)
-
Игорь Шевченко
[q]Аргументы последуют[/q]
Собственно во многих классах были общие вещи, которые в первом приближении можно было упростить дженериками. Но практика показала обратное
-
> Руководство хочет :)
замени все списки в проекте на списки (стандартные) с поддержкой дженериков. и польза будет и начальство порадуется и работы не много )
-
А можно подробнее что там практика показала и об чём это конкретно?
Мне больше интересно - как это устроено на низком уровне? И на Си и на Делфи.
Компилятор типа смотрит какие типы были использованы в коде и делает "развёртку" шаблона на много обычных классов? И подставляет в код конкретные сгенерированные типы?
З.Ы. Как вы делаете код на белом фоне и с нумерацией строк? Что за тег?
-
Удалено модератором
-
> Что за тег?
DELPHI в угловых скобках. Надо на главной странице написать
-
Удалено модератором
-
> Pavia © (09.08.16 13:02) [8]
> Вообще кто нибудь сравнивал дженирики на Си или Си# с теми
> что в Delphi?
В C# есть linq, с помощью которого работать с Generic коллекциями намного проще.