#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. Правильно — я изменил подход из-за этого