Как описать свойство класса?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Как описать свойство класса?

Сообщение alaken » 27.05.2011 10:44:58

Всем привет

Как описать свойство класса, чтобы к нему можно было обращаться либо по индексу либо по строковому значению, по аналогии как в delphi в свойстве
ChildNodes интерфейса IXMLNode

Пример Delphi:
Код: Выделить всё
Var
XMLNode: IXMLNode;
...
begin
...
//обращение по индексу
  ShowMessage(XMLNode.ChildNodes[2].NodeName);

//обращение по строковому значению
  ShowMessage(XMLNode.ChildNodes['TagName'].NodeName);

// оба варианта работают!

end


В исходниках FPC в описании класса TDOMNodeList описано подобное поле, но оно может быть единственным, то есть к такому полю можно обратится только по индексу, как сделать как в Delphi, чтобы дополнительно можно было обращаться и по строковому значению?
Пример из FPC:
Код: Выделить всё
protected
function GetItem(index: LongWord): TDOMNode;
...
public
property Item[index: LongWord]: TDOMNode read GetItem; default;

Чтобы было понятнее, можно реализовать следующим образом:
Код: Выделить всё
protected
function GetItem(Name: WideString): TDOMNode;
...
public
property Item[Name: WideString]: TDOMNode read GetItem; default;
к такому свойству можно обращаться по строковому значению, но по индексу уже нельзя...

Буду признателен, если кто нибудь, предложит решение или объяснит как реализовать.
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13

Re: Как описать свойство класса?

Сообщение Maxizar » 27.05.2011 11:30:59

Хм... знаете чисто самому стало интересно... думал что то хитрое, посмотрев исходники в Delphi, оказалось, что там это дело реализована, вот так:

Код: Выделить всё
    function GetNode(const IndexOrName: OleVariant): IXMLNode;

То есть через Вариантный тип, определяя который он видит, вы передали число или строку ну и вызывает ту или иную функцию...
Я практически никогда не работал в Варинтами, по этому извините...

Но знаете, я вот тут сделал через перегрузку функций, и если честно не понимаю, почему это работает, НО это реально работает вот:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

{ My1 }

My1 = class
  SL:TStringList;
  function GetValue(Index: Integer): String;
  function GetValue(Str: String): String; overload;

//private


//public
   property Value[Index:Integer]:String read GetValue;
   constructor Create;
   destructor Destroy; override;
end;
var
  Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var MyList:My1;
begin
    MyList:=My1.Create;

    //Caption:=MyList.SL.Values['FirstString'];

    //Caption:=MyList.Value[0];
    Caption:=MyList.Value['FirstString'];
    MyList.Free;
end;

{$R *.lfm}

{ My1 }

function My1.GetValue(Index: Integer): String;
begin
  Result:=SL.Values[SL.Strings[Index]];
end;

function My1.GetValue(Str: String): String;
begin
   Result:=SL.Values[Str];
end;

constructor My1.Create;
begin
  SL:= TStringList.Create;
  SL.Add('FirstString');
  SL.Values['FirstString']:='Value1';
end;

destructor My1.Destroy;
begin
  SL.Free;
  inherited Destroy;
end;

end.


Почему, компилятор не ругается Не понятно, ведь по идее свойство у нас требует Индекс, который явл-ся числом!.. так что не понятно вообще то что я сделал имеет право на жизнь или нет и можно ли так делать?... Ведь почему то все работает. Удивительно :!: :!: :!: :?:
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Как описать свойство класса?

Сообщение kipar » 27.05.2011 11:44:22

В дельфи это не работает, так что похоже на баг компилятора fpc. Кстати, дельфи еще требует поставить overload перед обоими объявлениями GetValue, а не перед одним.

Имхо если уж разрешать такое поведение, то надо заставить объявить свойство два раза, ну или как-то так:
Код: Выделить всё
property Value[Index]:String read GetValue;

А иначе получается путаница.
kipar
новенький
 
Сообщения: 78
Зарегистрирован: 04.03.2010 12:15:54

Re: Как описать свойство класса?

Сообщение alaken » 27.05.2011 11:51:17

Начал подумывать через вариантный тип реализовывать, недоглядел исходники дельфи (, глаз замылился..., а так бы и не было вопросов :oops:

С перегруженным методом и свойством, действительно интересно, возможно это одна из недокументированных особенностей.

Спасибо за подсказку.
Буду использовать вариантный тип.
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru