Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Дженерики - примеры где с ними было бы лучше   Найти похожие ветки 

 
Кто б сомневался ©   (2012-07-18 15:59) [0]

(намного?), чем без них.

Привет.
Начал тут почитывать про generics, никак не могу представить весь спектр ситуаций, где их можно было бы всунуть, те кто с ними уже работал могли бы вы привести простой пример(ы)?


 
И. Павел ©   (2012-07-18 16:08) [1]

Их основное применение — создание типизированных коллекций. Т.е. не List.Add(object) а List.Add(String) и т.д.


 
Давайте будем жрать!   (2012-07-18 16:10) [2]

with TObjectList<TObject>.Create(False) do begin
 Add(DS.Fields[0]);
 Items[I].FieldName := "qwerty";
end;


vs

with TObjectList.Create(False) do begin
 Add(DS.Fields[0]);
 if TObject(Items[I]) is TField then
   TField(Items[I]).FieldName := "qwerty";
end;


 
Давайте будем жрать!   (2012-07-18 16:11) [3]


> TObject(Items[I])

Пардон, приведение типа лишнее.


 
Компромисс ©   (2012-07-18 17:45) [4]

http://delphi.about.com/od/objectpascalide/a/understanding-generic-types-in-delphi.htm


 
Кто б сомневался ©   (2012-07-18 18:16) [5]


> Компромисс ©   (18.07.12 17:45) [4]


Не знаю для чего Вы привели эту ссылку. Как бы базовый пример показанный там следующий:

With the following definition, here"s how to use an integer and string generic container:
var
  genericInt : TGenericContainer<integer>;
  genericStr : TGenericContainer<string>;
begin
  genericInt := TGenericContainer<integer>.Create;
  genericInt.Value := 2009; //only integers
  genericInt.Free;

  genericStr := TGenericContainer<string>.Create;
  genericStr.Value := "Delphi Generics"; //only strings
  genericStr.Free;
end;


Что создает еще больше вопросов - в плане зачем городить такие огороды, если без дженериков короче и понятней, конкретно в данном примере.

Вопрос не в том как использовать их, а где их нужно использовать (Ваше мнение), в каких ситуациях. Возможно есть открытые сырцы где их использование оправдано как с т.з. читабельности (обобщенности алгоритма), так и производительности. Если есть, дайте ссылку пожалуйста. Или объясните без кода.
Спасибо.


 
Компромисс ©   (2012-07-18 18:31) [6]


> Не знаю для чего Вы привели эту ссылку.


Это была первая ссылка в поисковике по запросу "delphi generics tutorial".
Я на Delphi уже лет 5 не работаю, но все-таки смог оценить полезность.
Например, в Delphi Generics Tutorial (http://delphi.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=delphi&cdn=compute&tm=5&f=00&su=p284.13.342.ip_p504.6.342.ip_&tt=2& bt=0&bts=0&zu=http%3A//www.felix-colibri.com/papers/oop_components/delphi_generics_tutorial/delphi_generics_tutorial.html)  имеем

Why Generics ?
Life Before Generics
The First Generics Example
Using Parameterized Types
Constraints on Generic Types


Разве не это было нужно?


 
Кто б сомневался ©   (2012-07-18 18:52) [7]


> Разве не это было нужно?


Спасибо за помощь, но немного не то.
Там описывается как использовать данный функционал, и для того чтобы было понятно, приводятся упрощенные примеры.
Я эти статьи читал, часть из них бегло - т.к. они похожи. Также поискал\почитал перевод на tdelphiblog.com.
Мне (да и другим думаю также) интересно мнение тех кто уже использовал дженерики, либо просто знает где их органичней всего использовать. Были ссылки на исходный код как по вопросу [5], но ссылались они ну гуглокод, который закрыт (http://code.google.com/p/delphilhlplib/).


http://www.tdelphiblog.com/2009/07/2-generics-delphi-2009-win32-2.html
Dmitry Atamanov15 июля 2009 г., 8:28

Спасибо за статью !

А самое "массивное" применение новых возможностей Delphi 2009 я видел только в DeHL (http://code.google.com/p/delphilhlplib/).

IMHO, лучшая библиотека контейнеров, хотя в ней есть и "большие" числа, и своя реализация работы с датой/временем и многое другое.

Вот что то в этом роде.


 
Eraser ©   (2012-07-18 21:20) [8]


> Кто б сомневался ©   (18.07.12 15:59) 

почти где попало, очень полезное изобретение. любой список объектов.


 
wl ©   (2012-07-18 22:54) [9]


> И. Павел ©   (18.07.12 16:08) [1]

я бы добавил: для того, чтобы соответствия типов проверял компилятор на этапе компиляции, а не программист в рантайме (повышается безопасность кода).

а вообще, в других языках, они используются для обобщенного программирования. То есть, если разные типы объектов реализуют определенное поведение, то можно написать один обобщенный алгоритм, который будет работать с разными типами (не в одной иерархии наследования).
Классический пример: сортировка, требует тип, которые реализует операции "=" и "<", будет работать и с числами, и со строками


 
jack128_   (2012-07-18 22:58) [10]

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


 
Кто б сомневался ©   (2012-07-19 02:06) [11]


> jack128_   (18.07.12 22:58) [10]

Спасибо кэп. Вам бы политиком быть.

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

Вот лучшая статья по дженерикам из всех указанных по ссылкам выше.
http://keeper89.blogspot.com/2011/07/delphi-1.html


 
Petr V. Abramov ©   (2012-07-19 02:25) [12]


> Классический пример: сортировка, требует тип, которые реализует
> операции "=" и "<", будет работать и с числами, и со строками
>

в одном популярном языке это решено лет 40 назад.
как складывать доллары с евро, пишет один программист (со своим постановщиком), как сортировать результат - другой, читавший Кнудта :)


 
Германн ©   (2012-07-19 03:04) [13]


> Кто б сомневался ©   (19.07.12 02:06) [11]
>
>
> > jack128_   (18.07.12 22:58) [10]
>
> Спасибо кэп. Вам бы политиком быть.
>
> Про вторую фразу - я ж и ищу примеры


Примеры чего ты ищещь, о отрок?
Не смущайся, открой нам что тебя волнует.


 
Inovet ©   (2012-07-19 06:25) [14]

> [11] Кто б сомневался ©   (19.07.12 02:06)
> Про вторую фразу - я ж и ищу примеры - или в коде, или на
> словах где лучше использовать обобщенный, нетипизированный
> код.

На других языках смотри stl.


 
oxffff ©   (2012-07-19 10:24) [15]


> jack128_   (18.07.12 22:58) [10]
> механизмы для обобщенного программирования есть во всех
> более-менее популярных статически типизированных языках.
>  
> Чтобы оценить полезность дженериков достаточно выйти за
> рамки дельфи и посмотреть как пишут программы на других
> языках.


:)


 
Компромисс ©   (2012-07-19 11:07) [16]

Я чаще generic использую для сложных случаев типа

public interface MyInterface<T extends MyClass, C, R extends Collection<? extends C>>{
 public R myMethod1(T obj1);
 public boolean myMethod2(C obj1, T obj2);
...
}

и соотвественно

public class MyCustomInterfaceImpl implements MyInterface<MyClass2, MyClass3, List<MyClass4> {
...
}

чтобы заставить компилятор контролировать как можно больше за меня.


 
Кто б сомневался ©   (2012-07-19 15:07) [17]


> Inovet ©   (19.07.12 06:25) [14]
На других языках смотри stl.

Ты б еще сказал - загугли. Нет чтобы описать вкратце часто используемые на практике задачи.

То что меня интересовало, это в каких ситуациях их органичней использовать.

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

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


 
Компромисс ©   (2012-07-19 15:21) [18]

Кто б сомневался ©   (19.07.12 15:07) [17]


> То что меня интересовало, это в каких ситуациях их органичней
> использовать.


ИМХО неправильная постановка вопроса. Если они могут быть использованы, то они должны быть использованы, потому что они помогают писать более безопасные программы. То есть должна быть причина, по которой их не надо использовать там, где их использование возможно (производительность, низкая квалификация команды и т.д.).
То есть по сути вопрос похож на "Когда органично использовать String?"


 
Кто б сомневался ©   (2012-07-19 15:56) [19]


> Компромисс ©   (19.07.12 15:21) [18]


Вы не правы. Перефразируя вашу фразу

> "Если они могут быть использованы, то они должны быть использованы,
>  потому что они помогают писать более безопасные программы.
>


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

Дженерики по факту делают безопасной работу с приведеним типов (Type Cast) - а это как правило ошибки начинающих программистов. Поэтому говорить о том "что они помогают писать более безопасные программы" не верно, безопасные (= не глючные) программы пишут квалифицированные кадры.

У любого инструмента свое назначение. Если использовать дженерики везде, - результат станет менее производительным.


> То есть по сути вопрос похож на "Когда органично использовать String?"


У string четко определены границы функциональности (точнее у нее всего одно предназначение) поэтому нет смысла ставить так вопрос. ИМХО.


 
vuk ©   (2012-07-19 16:24) [20]

У меня вот такое есть - в пополаме с анонимными функциями:

TIterator<string>.ForEach(["string1", "string2", ..., "stringN"],
   procedure (const Item: string)
   begin
     //тут что-то усиленно делаем со строками
   end);


:)


 
Кто б сомневался ©   (2012-07-19 16:29) [21]


> vuk ©   (19.07.12 16:24) [20]


А мне кстати понравилась одна идея связанная с анонимными функциями:

Многопоточность – это хорошее применение для анонимных методов. Если вы хотите выполнять параллельно какой-то код, возможно вам пригодится функция на подобие этой:
type
 TProcOfInteger = reference to procedure(x: Integer);

procedure ParallelFor(start, finish: Integer; proc: TProcOfInteger);


Процедура ParallelFor работает в разных потоках. Предположим, что эта процедура правильно реализована, эффективно использует потоки в потоковом пуле и может быть легко использована для получения преимущества при работе с несколькими процессорами:
procedure CalculateExpensiveThings;
var
 results: array of Integer;
begin
 SetLength(results, 100);
 ParallelFor(Low(results), High(results),
   procedure(i: Integer)                   // \
   begin                                   //  \ блок кода
     results[i] := ExpensiveCalculation(i);//  /  используется
   end                                     // /  как параметр
   );
 // пользуемся результатами
 end;


Т.е. это можно было бы сделать вместо  TThread и его абстрактного метода Execute

http://pascal-study.blogspot.com/2012/03/delphi.html


 
Компромисс ©   (2012-07-19 16:44) [22]


> А это не так - основная задача - унификация кода для разных
> типов данных, а это далеко не всегда нужно.


Я как-то нарвался на то, что вдруг понабилась реализация того же самого алгоритма, но для другого типа. Пришлось вводить generic. С тех пор всегда в самом начале думаю, имеет ли смысл применение generic, и часто бывает, что сразу ввожу generic, хотя пока всего для одного типа есть реализация. Я вообще фанат generic, если незаметно )


> Дженерики по факту делают безопасной работу с приведеним
> типов (Type Cast) - а это как правило ошибки начинающих
> программистов


Начинающих или нет - неважно, шанс ошибиться всегда есть. Generic позволяют вовсе убрать приведение типа. К тому же, они выполняют функцию документирования. Сразу становится видно, что хранится в коллекции, например.
Вот есть у меня прямо сейчас List<Map<String, Object>> и никаких приведений типа не надо. Еще, например, в myMethod(T obj, String s) четко различаются аргументы по смыслу, даже если у нас есть всего одна реализация, для T=String.


 
jack128_   (2012-07-19 22:01) [23]


> У меня вот такое есть - в пополаме с анонимными функциями:
>
>
> TIterator<string>.ForEach(["string1", "string2", ..., "stringN"],
>
>    procedure (const Item: string)
>    begin
>      //тут что-то усиленно делаем со строками
>    end);
>
> :)

ужос какой.
Так не катит:

for s in TArray<string>.Create("string1", "string2", ..., "stringN") do
begin
...
end;

?


 
Inovet ©   (2012-07-19 22:14) [24]

> [17] Кто б сомневался ©   (19.07.12 15:07)
> > Inovet ©   (19.07.12 06:25) [14]
> На других языках смотри stl.
>
> Ты б еще сказал - загугли. Нет чтобы описать вкратце часто используемые на практике задачи.

Так в кратце можно в Вики список шаблонов прочитать
http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%BD%D0%B0%D1%8F_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2


 
icelex ©   (2012-07-20 02:33) [25]

если коллекция не используется для хранения разнородных данных, то дженерик


 
vuk ©   (2012-07-20 09:42) [26]

to jack128_   (19.07.12 22:01) [23]:

> ужос какой.

Никакого ужоса.

Так не катит:

Катит, конечно же. Тока у меня обходится без выделения динамической памяти под массив. ;)


 
jack128_   (2012-07-20 10:07) [27]


> Тока у меня обходится без выделения динамической памяти
> под массив. ;)

Зато выделяется память под лямбду.


 
Кто б сомневался ©   (2012-07-21 20:37) [28]


> icelex ©   (20.07.12 02:33) [25]
>
> если коллекция не используется для хранения разнородных
> данных, то дженерик


Как бы наоборот


 
Давайте будем жрать!   (2012-07-21 23:37) [29]

Как бы наоборот наоборот.

[25] имел в виду, что в обычном листе можно хранить, например, стринги и объекты, а в ТЛист«стринг» — только стринги


 
Плохиш ©   (2012-07-22 01:37) [30]

В визуальной студии полно примеров использования. Весь LINQ на них построен.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.067 c
15-1331316742
Artem
2012-03-09 22:12
2013.03.22
Windows 7 Семейная


15-1337598756
p
2012-05-21 15:12
2013.03.22
Сертификат Verisign


1-1297521334
Slava.yo
2011-02-12 17:35
2013.03.22
Автопрокрутка в Webbrowser


2-1339314251
СветаНеМогуСделать
2012-06-10 11:44
2013.03.22
Массивы и символьные строки


2-1329825696
TurikUs
2012-02-21 16:01
2013.03.22
Delphi 2010





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский