Ошибка DCC …: E2010 Несовместимые типы: ‘integer’ и ‘Integer’

#delphi #generics #interface #delphi-xe

#delphi #общие #интерфейс #delphi-xe

Вопрос:

Попытка построить интерфейс и график на основе обобщений и получение нечетной ошибки — обратите внимание на разницу в регистре в слове ‘integer’ в строке ошибки.

Анализатор текста передается в реализацию Graph, а затем вызывается Graph для построения его базовой структуры данных. Другие объекты IGraphConstructor могут создавать более сложные фактические графики, а не просто заполнять базовый словарь.

 IGraphConstructor<K,V> = interface
  function Construct(AData : TObjectDictionary<K,V>) : boolean;
end;

IGraph<K,V> = interface
  ['{B25EEE1F-3C85-43BB-A56B-3E14F7EA926C}']
  function Construct(AConstructor : IGraphConstructor<K,V>) : boolean;
  function GetNodes : TObjectDictionary<K,V>;
  property Nodes : TObjectDictionary<K,V> read GetNodes;
end;

TGraph<K,V> = class(TComponent, IGraph<K,V>)
private
  FData : TObjectDictionary<K,V>;
  function GetNodes : TObjectDictionary<K,V>;
... 

//the editor
TVirtualEditor = class(TComponent)
private
  FGlyphs : TGraph<integer,TGlyph>;
...  

TTextParser<integer,TGlyph> = class(TInterfacedObject, IGraphConstructor<integer,TGlyph>)
... 
  

и…

 function TVirtualEditor.Edit(AText: string): boolean;
var
  parser : TTextParser<integer,TGlyph>;
begin
  parser := TTextParser<integer,TGlyph>.Create(AText);
  result := FGlyphs.Construct(parser);
end;

function TTextParser<integer,TGlyph>.Construct(AData: TObjectDictionary<integer,TGlyph>): boolean;
var
  i : integer;
begin
  for i := 1 to length(FText) do
  begin
    //#1
    AData.AddOrSetValue(i, TGlyph(TCharGlyph.Create( FText[i] )) ); //!--> error [DCC Error] ...: E2010 Incompatible types: 'integer' and 'Integer'
  end;

  //uc....

end;
  

Объявление TTextParser как TTextParser<K,V> и использование его как

 TParser : TTextParser<integer,TGlyph>;
  

возвращает и ошибка в # 1 из

 [DCC Error] ...: E2010 Incompatible types: 'K' and 'Integer'
  

РЕДАКТИРОВАТЬ: обходной путь

Нашел обходной путь, но не уверен, что это способ сделать это.

 function TTextParser<K,V>.Construct(AData: TObjectDictionary<K,V>): boolean;
var
  i : integer;
  n : K;
  o : V;
begin
  for i := 1 to length(FText) do
  begin
    n := K((@i)^);
    o := V(TCharGlyph.Create( FText[i] ));
    AData.AddOrSetValue(n, o );
  end;
  result := true;
end;
  

Ответ №1:

Строка

 TTextParser<integer,TGlyph> = class(TInterfacedObject, IGraphConstructor<integer,TGlyph>)
  

описывает универсальный тип, в котором двумя используемыми именами универсального типа являются integer и TGlyph (как K и V в IGraph<K,V> ). Это всего лишь заполнители, и их не следует путать с существующими типами integer и TGlyph .

Ответ №2:

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

Если вам действительно нужен особый случай, есть обходной путь: затем вы можете сравнить информацию о типе (для этого вам нужно включить unit TypInfo ):

 if (TypeInfo(K) = TypeInfo(Integer)) then
  begin
  // special case
  end;
  

Комментарии:

1. Правильно — я изменил подход из-за этого