Как обрабатывать простые типы Delphi при использовании универсальных шаблонов?

Небольшой пример

TTest<T> = class
private
  f : T;
public
  function ToString : string;
end;

Если это объект, то это должно работать

TTest<T>.ToString;
begin
  Result := f.ToString;
end;

Но что происходит, если, скажем, целое число? Это было бы нормально в .net. конечно.

Я знаю, что это не сработает, но как мне написать код для работы с объектами И простыми типами?

T - это тип, а не значение. Ваш код должен выглядеть примерно так: var x: T; begin Результат: = x.ToString; конец;

Barry Kelly 04.11.2008 02:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
1 584
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Последний пример работать не будет. Вам нужно добавить ограничение, чтобы использовать методы. В этом случае будет достаточно TObject:

TTest<T: TObject>.ToString;
begin
  Result := T.ToString;
end;

Вы можете использовать простые типы с неограниченными обобщениями, но вы очень ограничены в использовании. Потому что единственные допустимые операции - это присваивание и сравнение (равно и не равно).

В Delphi простые типы не являются классами, поэтому у них нет методов. Но вы можете сделать следующее:

type
  TToString<T> = reference to function(const AValue: T): string;
  TGenContainer<T> = class
  private
    FValue: T;
    FToString : TToString<T>;
  public
    constructor Create(const AToString: TToString<T>);

    function ToString: string;

    property Value: T read FValue write FValue;
  end;

constructor TGenContainer<T>.Create(const AToString: TToString<T>);
begin
  FToString := AToString;
end;

function TGenContainer<T>.ToString: string;
begin
  Result := FToString(FValue);
end;



procedure TForm2.Button1Click(Sender: TObject);
var
  gen : TGenContainer<Integer>;
begin
  gen := TGenContainer<Integer>.Create(
    function(const AValue: Integer): string
    begin
      Result := IntToStr(AValue);
    end);
  try
    gen.Value := 17;
    Memo1.Lines.Add(gen.ToString);
  finally
    gen.Free;
  end;
end;

Это прекрасно работает.

да, я знаю это, но как мне заставить его работать. Он отлично работает в .net, потому что все является объектом.

Steve 04.11.2008 02:01

Думаю, я мог бы обернуть свои простые типы объектами и переопределить функцию ToString, но это противоречит цели дженериков.

Ага, у простых типов нет методов.

Toon Krijthe 04.11.2008 02:05
Ответ принят как подходящий

Есть три причины, по которым Delphi не позволяет вам делать то, что вы пытаетесь сделать во втором примере - вызывать метод ToString для значения типа параметра неограниченного типа (или, по крайней мере, то, что я думаю, вы пытались показать, поскольку TObject.ToString - это метод экземпляра, а не метод класса, поэтому T.ToString не будет работать даже для TObject).

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

  2. Исходя из пункта 1, почему операции ограничиваются этим? Почему бы не разрешить операции в универсальном классе и выдать ошибки только во время создания экземпляра? Что ж, первая часть причины заключается в том, что дизайн изначально был предназначен для максимальной совместимости с .NET и dccil, поэтому вещи, которые не допускались универсальными шаблонами .NET, не имели существенных возможностей в дизайне универсальных шаблонов Win32.

  3. Второе обоснование дизайна состоит в том, что проверка только во время создания экземпляра проблематична. Самая известная реализация параметрического полиморфизма, использующая этот подход, - это шаблоны C++, и она также известна своими загадочными сообщениями об ошибках, как вы, например, попробуйте передать в алгоритм неправильный тип итератора и получите странные жалобы на то, что перегруженные операторы не найдены. Чем глубже полиморфизм, тем хуже проблема. На самом деле, это так плохо, что C++ сам исправляет эту ошибку в виде концепций C++ 0x.

Надеюсь, теперь вы понимаете, почему нельзя использовать операции, доступность которых не гарантируется через ограничения. Однако вы можете относительно легко обойти это ограничение, предоставив операцию в форме ссылки на метод или реализации интерфейса, как предлагает Gamecat.

В будущем универсальные шаблоны в Delphi для Win32, вероятно, будут расширены по аналогии с концепциями C++ 0x или классами типов Haskell, так что параметры типа могут быть ограничены доступными определенными методами, функциями и операторами. Если он идет по линиям классов типов, то вывод типа может продолжаться таким же образом.

Другие вопросы по теме