Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода / 17 сообщений из 17, страница 1 из 1
29.04.2019, 10:57
    #39807473
harisma
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Здравствуйте. Такой вопрос.
Хочу реализовать метод в своем классе, который одним из параметров принимал бы или TDBGrid или TCRDBGrid (по крайней мере, пока эти 2 типа). Знаю, что оба класса порождены от TCustomDBGrid. И собственно на этом можно было бы и остановиться, объявив тип этого параметра как TCustomDBGrid, но тогда возникает вопрос, как красиво с этим объектом внутри метода работать? То есть, вызываю я это метод в программе, передавая в него или один или другой грид. А вот дальше как быть? У TCustomDBGrid я ко многим методам не имею доступа, в частности к тем, какие у него объявлены в секции protected. ОбЪявлять внутри метода внутренние переменные нужных типов и делать приведение типов входного параметра - тоже как-то не хочется, ибо код для этих разных типов гридов по сути тот же самый (вызываю те же самые методы и свойства), потому не хотелось бы делать повторение кода. Осознаю, что можно было бы сделать перегрузку этого метода (создать 2 метода с разными типами параметров) - но это опять таки повторение кода.
Существует ли способ, сделать это красиво? И если да, то как? Заранее благодарю за ответ.
...
Рейтинг: 0 / 0
29.04.2019, 11:07
    #39807479
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Это не описание задачи, а, возможно, не лучшее её решение.

Без примера кода это будет лишь философствование на тему...
...
Рейтинг: 0 / 0
29.04.2019, 11:15
    #39807487
harisma
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
wadmanЭто не описание задачи, а, возможно, не лучшее её решение.

Без примера кода это будет лишь философствование на тему...

Ок.
Вот пример кода:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
procedure TMyWrapper.InternalExportCRDBGridData(ADBGrid: TCRDBGrid; WS: OleVariant;
  AAllColumn: Boolean = False; AOnlyCurrentRow: Boolean = False);
var
  col, row: Integer;
  sline: string;
begin
  sline := '';
  // add the info for the column names
  for col := 0 to ADBGrid.FieldCount - 1 do
    if ADBGrid.Columns[col].Visible or AAllColumn then
      sline := sline + ADBGrid.Columns[col].Title.Caption + #9;

  FMemo.Lines.Add(sline);

  // get the data into the memo
  if not AOnlyCurrentRow then
    for row := 0 to ADBGrid.DataSource.DataSet.RecordCount - 1 do
    begin
      sline := '';
      for col := 0 to ADBGrid.FieldCount - 1 do
        if ADBGrid.Columns[col].Visible or AAllColumn then
          sline := sline + ADBGrid.Fields[col].AsString + #9;
      sline := StringReplace(StringReplace(StringReplace(sline, #13#10, ' ', [rfReplaceAll]), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      ADBGrid.DataSource.DataSet.Next;
      FMemo.Lines.Add(sline);
    end
  else
  begin
    sline := '';
    for col := 0 to ADBGrid.FieldCount - 1 do
      if ADBGrid.Columns[col].Visible or AAllColumn then
        sline := sline + ADBGrid.Fields[col].AsString + #9;
    sline := StringReplace(StringReplace(StringReplace(sline, #13#10, ' ', [rfReplaceAll]), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
    FMemo.Lines.Add(sline);
  end;
  ........... 
end;

procedure TMyWrapper.InternalExportDBGridData(ADBGrid: TDBGrid; WS: OleVariant;
  AAllColumn: Boolean = False; AOnlyCurrentRow: Boolean = False);
var
  col, row: Integer;
  sline: string;
begin
  sline := '';
  // add the info for the column names
  for col := 0 to ADBGrid.FieldCount - 1 do
    if ADBGrid.Columns[col].Visible or AAllColumn then
      sline := sline + ADBGrid.Columns[col].Title.Caption + #9;

  FMemo.Lines.Add(sline);

  // get the data into the memo
  if not AOnlyCurrentRow then
    for row := 0 to ADBGrid.DataSource.DataSet.RecordCount - 1 do
    begin
      sline := '';
      for col := 0 to ADBGrid.FieldCount - 1 do
        if ADBGrid.Columns[col].Visible or AAllColumn then
          sline := sline + ADBGrid.Fields[col].AsString + #9;
      sline := StringReplace(StringReplace(StringReplace(sline, #13#10, ' ', [rfReplaceAll]), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      ADBGrid.DataSource.DataSet.Next;
      FMemo.Lines.Add(sline);
    end
  else
  begin
    sline := '';
    for col := 0 to ADBGrid.FieldCount - 1 do
      if ADBGrid.Columns[col].Visible or AAllColumn then
        sline := sline + ADBGrid.Fields[col].AsString + #9;
    sline := StringReplace(StringReplace(StringReplace(sline, #13#10, ' ', [rfReplaceAll]), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
    FMemo.Lines.Add(sline);
  end;
  ........... 
end;


А я хотел бы иметь вместо этих 2 фактически одинаковых методов, один, но который бы работал с обеими из этих типов гридов.
...
Рейтинг: 0 / 0
29.04.2019, 11:26
    #39807503
Hammer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
harisma,
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
unit UMyWrapper;

interface

uses
...

type
  TMyWrapper = class  
...
    procedure TMyWrapper.InternalExportCRDBGridData(ADBGrid: TCustomDBGrid; WS: OleVariant;
  AAllColumn: Boolean = False; AOnlyCurrentRow: Boolean = False);
...
  end;

...

implementation

uses
...

type
  TCustomDBGridAccess = class(TCustomDBGrid);

...
procedure TMyWrapper.InternalExportCRDBGridData(ADBGrid: TCustomDBGrid; WS: OleVariant;
  AAllColumn, AOnlyCurrentRow: Boolean);
var
  col, row: Integer;
  sline: string;
begin
...
  col := TCustomDBGridAccess(ADBGrid).ProtectedProperty;
...
end
...
...
Рейтинг: 0 / 0
29.04.2019, 11:28
    #39807506
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
harisma,

можно передавать не grid, а связанный с ним dataset. Получится более универсально.
...
Рейтинг: 0 / 0
29.04.2019, 11:37
    #39807516
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
harisma,

хочу дать небольшой комментарий к коду выше от Hammer'a

этот момент:
Код: pascal
1.
2.
type
  TCustomDBGridAccess = class(TCustomDBGrid);



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

И, кстати, я бы назвал не TCustomDBGridAccess, а по аналогии со многими библиотеками, TCustomDBGridCracker (мое предпочтение) или TCustomDBGridHack
...
Рейтинг: 0 / 0
29.04.2019, 11:39
    #39807520
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
harisma
Код: pascal
1.
2.
if not AOnlyCurrentRow then
    for row := 0 to ADBGrid.DataSource.DataSet.RecordCount - 1 do


Так не стоит делать, т.к. не все записи могут быть на клиенте в данный момент.

Как должно быть:
Код: pascal
1.
2.
3.
4.
DataSet.First;
while not DataSet.Eof do begin
  DataSet.Next;
end;
...
Рейтинг: 0 / 0
29.04.2019, 11:40
    #39807523
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
P.S.

и вот так этот хак используется:
Код: pascal
1.
   col := TCustomDBGridAccess(ADBGrid).ProtectedProperty
...
Рейтинг: 0 / 0
29.04.2019, 11:48
    #39807530
harisma
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Кроик Семён, Hammer, wadman: Всем спасибо. Помогли вспомнить, ибо когда-то именно так и делал. (в смысле, создавал Кракед класс от предка, чтоб получить доступ к протектед методам). Один ньюанс - место объявления этого класса. Я его пытался объявлять ы секции interface - и не работало. Щас попробую ваш способ.
...
Рейтинг: 0 / 0
29.04.2019, 12:01
    #39807540
Hammer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
harismaКроик Семён, Hammer, wadman: Всем спасибо. Помогли вспомнить, ибо когда-то именно так и делал. (в смысле, создавал Кракед класс от предка, чтоб получить доступ к протектед методам). Один ньюанс - место объявления этого класса. Я его пытался объявлять ы секции interface - и не работало. Щас попробую ваш способ.
Не могет токого быть, правда если объявление было в том же модуле что и класс
...
Рейтинг: 0 / 0
29.04.2019, 18:54
    #39807861
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Более красиво использовать класс-хелпер для доступа к протектед потрохам
...
Рейтинг: 0 / 0
30.04.2019, 07:40
    #39808098
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
white_niggerБолее красиво использовать класс-хелпер для доступа к протектед потрохам
Осталось только понять - зачем? Если смотреть на приведенный выше код.
...
Рейтинг: 0 / 0
30.04.2019, 10:59
    #39808210
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
wadmanwhite_niggerБолее красиво использовать класс-хелпер для доступа к протектед потрохам
Осталось только понять - зачем? Если смотреть на приведенный выше код.grid настройки для показа содержит(сильно не вникал что он там творит)

хелпер реально правильнее, приведения типов делают код потенциально опасным
...
Рейтинг: 0 / 0
13.05.2019, 15:33
    #39812571
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
1. Экспорт из грида не очень правильно, разумнее в самом деле обращаться сразу к датасету. Если какие-то вещи нужно брать от грида, можно их заранее извлечь (список выделенных записей, например) и передать параметром.
2. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомками (очевидно, но тем не менее).
3. Решение вполне имеет право на жизнь, но в дальнейшем может потребовать переделки (например, экспорт из другого источника, который не получится натянуть на общий глобус, или какие-то специфические фичи).
4. По приведенному коду - экспорт одной записи можно выделить в подпрограмму, чтобы не повторялся код, либо сделать один цикл и условие if OnlyCurrentRow then Break else Dataset.Next
...
Рейтинг: 0 / 0
13.05.2019, 15:52
    #39812582
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
procedure TMyWrapper.InternalExportCRDBGridData(ADataSet: TDataSet; WS: OleVariant;
  AAllColumn: Boolean = False; AOnlyCurrentRow: Boolean = False);
var
  Fields: TList<TField>;
  col, row: Integer;
  sline: string;
begin
  Fields := TList<TField>.Create;
  try
    for col := 0 to ADataSet.FieldCount - 1 do begin
      if AAllColumn or ADataSet.Fields[col].Visible then
        Fields.Add(ADataSet.Fields[col]);
    end;
    if Fields.Count = 0 then
      Exit;

    sline := '';
    // add the info for the column names
    for col := 0 to Fields.Count - 1 do
      sline := sline + Fields[col].DisplayLabel + #9;
    FMemo.Lines.Add(sline);

    while not ADataSet.Eof do begin
      sline := '';
      for col := 0 to Fields.Count - 1 do
        sline := sline + Fields[col].Text+ #9;
      sline := StringReplace(StringReplace(StringReplace(sline, #13#10, ' ', [rfReplaceAll]), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      FMemo.Lines.Add(sline);
      if AOnlyCurrentRow then
        Break;
      ADataSet.Next;
    end;
  finally
    Fields.Free;
  end;
  ........... 
end;

...
Рейтинг: 0 / 0
13.05.2019, 15:54
    #39812584
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Василий 22. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомкамиС какого перепугу?
...
Рейтинг: 0 / 0
14.05.2019, 10:20
    #39812825
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
_Vasilisk_Василий 22. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомкамиС какого перепугу?
С большого.
Перекрыл ты в TChild невиртуальный метод Foo, а потом вызываешь TParent(Child).Foo, что получится? Правильно, ерунда
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]