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

Без примера кода это будет лишь философствование на тему...
...
Рейтинг: 0 / 0
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #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
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #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
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #39807506
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
harisma,

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

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

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



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

И, кстати, я бы назвал не TCustomDBGridAccess, а по аналогии со многими библиотеками, TCustomDBGridCracker (мое предпочтение) или TCustomDBGridHack
...
Рейтинг: 0 / 0
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #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
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #39807523
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.

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

хелпер реально правильнее, приведения типов делают код потенциально опасным
...
Рейтинг: 0 / 0
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #39812571
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Экспорт из грида не очень правильно, разумнее в самом деле обращаться сразу к датасету. Если какие-то вещи нужно брать от грида, можно их заранее извлечь (список выделенных записей, например) и передать параметром.
2. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомками (очевидно, но тем не менее).
3. Решение вполне имеет право на жизнь, но в дальнейшем может потребовать переделки (например, экспорт из другого источника, который не получится натянуть на общий глобус, или какие-то специфические фичи).
4. По приведенному коду - экспорт одной записи можно выделить в подпрограмму, чтобы не повторялся код, либо сделать один цикл и условие if OnlyCurrentRow then Break else Dataset.Next
...
Рейтинг: 0 / 0
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #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
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #39812584
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 22. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомкамиС какого перепугу?
...
Рейтинг: 0 / 0
Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
    #39812825
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Василий 22. Два класса-потомка приводить насильно к общему знаменателю можно, но только если используемые методы виртуальные либо не перекрывались потомкамиС какого перепугу?
С большого.
Перекрыл ты в TChild невиртуальный метод Foo, а потом вызываешь TParent(Child).Foo, что получится? Правильно, ерунда
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Тип параметра метода, и работа с этим параметртром внутри метода без повторения кода
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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