В Delphi.Net есть хэлперы, которые увеличивают функциональность нетовских классов. В связи с этим вопросы.
1. Написание хэлперов это прераготива Борланда или она доступна любому.
2. Какова область видимости всех членов класса при написании Хэлперов к нему, или все как при наследовании.
3. Какую еще дополнительные фунциональность через них можно добавлять, кроме методо (интерфейсы, поля, итд)
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Serginio1, Вы писали: S>Да вроде как отказались они от хелперов же... Или нет?
Да нет. Без Хэлперов имбы пришлось делать свои классы оболочки над нетовскими, а это не удобно легче добавить функциональность для совместимости с Дельфевыми через Хэлперы.
Мне они сразу понравились, особенно когда нужно вдруг добавить классу функциональность, то нужно создавать класс наследник, переписывать в уже созданном коде типы и конструкторы, а с хэлперами просто добавил свой класс и прописал дополнительную функциональнось. Еще одна степень свободы.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, Serginio1, Вы писали: S>>Да вроде как отказались они от хелперов же... Или нет?
S> Да нет. Без Хэлперов имбы пришлось делать свои классы оболочки над нетовскими, а это не удобно легче добавить функциональность для совместимости с Дельфевыми через Хэлперы.
Нэт и исчо раз Нэт... в Delphi 8 class helpers нэ присутствуют... они были только в Delphi for .Net Preview
... << RSDN@Home 1.1.3 beta 2 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуйте, Hacker_Delphi, Вы писали:
S>> Да нет. Без Хэлперов имбы пришлось делать свои классы оболочки над нетовскими, а это не удобно легче добавить функциональность для совместимости с Дельфевыми через Хэлперы. H_D>Нэт и исчо раз Нэт... в Delphi 8 class helpers нэ присутствуют... они были только в Delphi for .Net Preview
Тогда как достигается совместимость нетовского Object с TObject ????
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Hacker_Delphi, Вы писали:
S>>> Да нет. Без Хэлперов имбы пришлось делать свои классы оболочки над нетовскими, а это не удобно легче добавить функциональность для совместимости с Дельфевыми через Хэлперы. H_D>>Нэт и исчо раз Нэт... в Delphi 8 class helpers нэ присутствуют... они были только в Delphi for .Net Preview S> Тогда как достигается совместимость нетовского Object с TObject ????
type
TObject = System.Object;
//...
TComponent = System.ComponentModel.Component;
а вот все остальное (в VCL.Forms — совсем свое и несовместимое )
... << RSDN@Home 1.1.3 beta 2 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
H_D>а вот все остальное (в VCL.Forms — совсем свое и несовместимое )
Так вот и вопрос у
1. У ТObject много статических виртуальных методов, впрочем как и у TComponent перекрываемых в наследуемых классов (в том числе и Виртуальные Конструкторы) и поддерживаемых в Delphi.Net.
2. Другие методы и поля.
Могу ошибаться, но Орлик говорил как раз о совместимости с помощью Хэлперов.
К сожалению пираты не слишком поворотливы да и уже первый апдейт появился. Очень хочется ее посмотреть.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Hacker_Delphi, Вы писали:
H_D>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, Sinclair, Вы писали:
S>>>Здравствуйте, Serginio1, Вы писали: S>>>Да вроде как отказались они от хелперов же... Или нет?
S>> Да нет. Без Хэлперов имбы пришлось делать свои классы оболочки над нетовскими, а это не удобно легче добавить функциональность для совместимости с Дельфевыми через Хэлперы. H_D>Нэт и исчо раз Нэт... в Delphi 8 class helpers нэ присутствуют... они были только в Delphi for .Net Preview
Есть там хелперы , только всего три — для Tobject для TComponent и для TPresistent
unit Borland.Delphi.System;
TObjectHelper = class helper for TObject
public
procedure Free;
function ClassType: TClass;
class function ClassName: string;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: System.Type;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const AName: string): TMethodCode;
class function MethodName(ACode: TMethodCode): string;
function FieldAddress(const AName: string): TObject;
procedure Dispatch(var Message);
end;
и
unit Borland.Vcl.Classes;
TPersistentHelper = class helper (TObjectHelper) for TPersistent
private
procedure AssignError(Source: TPersistent);
protected
procedure AssignTo(Dest: TPersistent); virtual;
procedure DefineProperties(Filer: TFiler); virtual;
function GetOwner: TPersistent; virtual;
public
constructor Create;
procedure Assign(Source: TPersistent); virtual;
function GetNamePath: string; virtual;
function GetRootDesigner: IDesignerNotify; virtual;
end;
TComponentHelper = class helper (TPersistentHelper) for TComponent
private
function GetComponents(Index: Integer): TComponent;
и тд
TComponentHelper — IMHO это типа перходник между VCL и нетовским Component, потому что
TComponent объявлен как
TComponent = System.ComponentModel.Component;
наверно можно добавлять свои хелперы, правда я не пробовал... (похоже что надо наследоваться от базового TObjectHelper)
кстати если сравнить diffom исходники VCL у 7 и 8, то не очень много различий
.Free и деструкторы остались
строки теперь объекты и можно написать s.Метод , так даже удобнее...
а еще обещают летом Delphi 8 for Win32 здесь даже есть Preview
Здравствуйте, Hacker_Delphi, Вы писали:
H_D>Но зато как они их спрятали-то а обещали-то — на кажный контрол по хелперу... видать передумали
Ежели передумали, тогда
Может пока апробируют? Технология ещё новая, неотлаженная
— щас сразу засветится — все начнут доопределять классы хэлперами — может получиться
думаю ещё ( ) — на них косвенно и M$ давит , может там недовольны..
Ведь эта "степень свободы" очень перспективная — жить будет — не беспокоимся...
сам года два назад просёк это дело (без катализационно-тотализационных шагов со стороны "Точки НЕТ" ), а оно вот — взяло и появись
глядя на множество однообразных библиотек компонентов и контролов, дополняющих каждая по-чуть-чуть функциональность этих классов, подумалось: почему не сделают такие расширения классов (expanse - так бы может их обозвать), чтоб "сторонним производителям" можно было легко переопределять до компиляции классы ( или несколько в их иерархии — так же как экспонируют её тип-интерфейсами), а "фирменные" unit об этом лишний раз "не задумывались"
тогда Borland это сильно "не поджимало": многие вот библиотеки свои пишут — разнообразие получается (однообразное ), исходники плодятся и множутся, а им что до этого было?
А теперь вот во времена "Точки" видать "поджало"...и вдруг им вспомнлось что-то наподобие: "Не плоди сущностей сверх необходимого"
а проще писать что-то такое:
----------------------
unit DomainMain.UnitName;
type X = class
...
----------------------
unit DomainExpanse.UnitName;
uses DomainMain.UnitName;
type Y = expanse (X)
...
----------------------
unit DomainInherit.UnitName;
uses DomainMain.UnitName {$ifdef DomainExpanseAddUse}, DomainExpanse.UnitName{$ifend};
type Z = class (X)
...
----------------------
очень хороший инструмент "асинхронной разработки" получается — подключаешь кикие надо расширения и компилируешь... только языковую конструкцию бы отшлифовать на предмет приоритетов этих expanse от "разных поставщиков" и др. технич. моменты...
Наконец то попало это чудо мне в руки. Интересно было посмотреть не только на хэлперы но и на реализацию виртуальных конструктороа и статических виртуальных методов. Чудо не произошло решаетс через метаклассы. Может кому интересно.
unit Class1;
interface
type
TVclass= class of TVirtClass;
TVirtClass = class
strict private
class var// Introduce a block of class static fields.
Red: Integer;
class constructor Create;
private{ Private Declarations }
FName:String;
public
constructor Create; overload; virtual;
constructor Create(Const St:String); overload; virtual;
Function ToString:String; override;
class Function StaticVirt:String; virtual;
end;
TVirtClassHerlper= class helper for TVirtClass
public
Function MyFunc:String;
end;
TVirtClass1 = class(TVirtClass)
constructor Create; overload; override;
constructor Create(Const St:String); overload; override;
class Function StaticVirt:String; override;
end;
TVirtClass2 = class(TVirtClass)
constructor Create; overload; override;
constructor Create(Const St:String); overload; override;
class Function StaticVirt:String; override;
end;
function GetClassName(AClass:TVclass):String;
implementation
constructor TVirtClass.Create;
begin
inherited Create;
// TODO: Add any constructor code hereend;
constructor TVirtClass.Create(const St: &String);
begin
inherited Create;
self.FName:=st;
end;
class constructor TVirtClass.Create;
begin
red:=666;
end;
class function TVirtClass.StaticVirt: String;
begin
result:= red.ToString;
end;
function TVirtClass.ToString: String;
begin
result:=Fname;
end;
{ TVirtClassHerlper }function TVirtClassHerlper.MyFunc: String;
begin
result:=toString+' TVirtClassHerlper'end;
{ TVirtClass1 }constructor TVirtClass1.Create;
begin
inherited;
FName:='TVirtClass31'end;
constructor TVirtClass1.Create(const St: &String);
begin
inherited;
self.FName:=st;
end;
class function TVirtClass1.StaticVirt: String;
begin
result:='TVirtClass1.StaticVirt'end;
{ TVirtClass2 }constructor TVirtClass2.Create;
begin
inherited;
FName:='TVirtClass32'end;
function GetClassName(AClass:TVclass):String;
begin
result:= Aclass.Create.ToString;
end;
constructor TVirtClass2.Create(const St: &String);
begin
inherited;
self.FName:=st;
end;
class function TVirtClass2.StaticVirt: String;
begin
result:='TVirtClass2.StaticVirt'end;
end.
К аждому лассу создается внутренний класс '@Meta'+ClassName
Например
public @MetaTVirtClass = class(@TClass)
public
constructor Create;
function @Create: TObject; virtual;
function @Create([in] St: String): TObject; virtual;
function StaticVirt: String; virtual;
static @Instance: @MetaTVirtClass;
strict private
constructor Create;
end;
Вызовы статических виртуальных методов в вызовы виртуальных методов метакласса.
class function Unit.GetClassName(AClass: @MetaTVirtClass): String;
var text1: String;
begin text1:= (AClass.@Create as TVirtClass).ToString;
result:= text1
end;
По поводу хэлперов то в рефлекторе они ведут себя как методы экземпляра класса
TVirtClass2.Create.MyFunc
хотя описание функции класса хэлпера следующее
class function TVirtClassHerlper.MyFunc(Self: TVirtClass): String;
var text1: String;
begin text1:= String.Concat(Self.ToString, ' TVirtClassHerlper');
result:= text1
end;
В общем достаточно интересно и возмоможности использования статических виртуальных методов
и расширение функциональности за счет хэлперов.
и солнце б утром не вставало, когда бы не было меня
Hello, Serginio1!
S> 1. Написание хэлперов это S> прераготива Борланда или она доступна любому.
Если я првавильно путаю, это просто "отображение" некоторых свойств
КОМПИЛЯТОРА, т.е. кроме как в Delphi нигде не возможно.
Ссылку после дихастера не найду, но кажется где-то на http://homepages.borland.com/abauer/
Я вообще не понимаю, почему .NET и C# проектировал бывщий архитектор Delphi,
и там нету до сих пор виртуальных конструкторов, и типа TClass
--
[tip] Fix for Outlook Express quoting: http://Arioch.nm.ru/FL/Fidolook_SL.png
E-mail is faked because of spam. the_Arioch@NM.falseDomain.ru
Здравствуйте, mister-AK, Вы писали:
MA>Здравствуйте, Serginio1, Вы писали:
S>>3. Какую еще дополнительные фунциональность через них можно добавлять, кроме методо (интерфейсы, поля, итд)
MA>самое неприятное, что поля-переменные добавить не удалось неужели это не6 реализуемо?
Поля и интерфейсы, а также переопределение виртуальных методв сделать нельзя, т.к. на создание экземпляра этого типа уже нельзя никак воздействовать.
А видимость методов только public.
Кстати методы хэлперов на самом деле статические, например
Объявленная функция в хэлпере
public function MyFunc: String;
на самом деле
public static string MyFunc(TVirtClass Self);
public class function MyFunc(Self: TVirtClass): String;
Но если наследуешься от этого объекта, то все методы класса хэлпера автоматически прописыватся в классе наследнике
и солнце б утром не вставало, когда бы не было меня
Function GetClassStaticName(v:Tobject):String;
begin
result:= TVclass(v.ClassType).StaticVirt
end;
Преобразуется в
class function Unit.GetClassStaticName(v: TObject): String;
var text1: String;
begin text1:= (TObjectHelper.ClassType(v) as @MetaTVirtClass).StaticVirt;
result:= text1
end;
Но вот TObjectHelper.ClassType
class function TObjectHelper.ClassType(Self: TObject): @TClass;
var class1: @TClass;
begin class1:= Unit.@GetMetaFromHandle(TObjectHelper.ClassInfo(Unit.@GetMetaFromObject(Self)).TypeHandle);
result:= class1
end;
class function TObjectHelper.ClassInfo(Self: @TClass): Type;
var type1: Type;
begin type1:= (Self as @TClass).InstanceType;
result:= type1
end;
Безобидный на первый взгляд, вместо старго получения адреса VMT
трансформируется
{ _TClass }var
MetaTypeMap: Hashtable;
procedure InitMetaTypeMap;
begin
if not Assigned(MetaTypeMap) then
MetaTypeMap := Hashtable.Create;
end;
function _GetMetaFromHandle(ATypeHandle: System.RuntimeTypeHandle): _TClass;
var
t, save: System.Type;
ancestor: _TClass;
ctorInfo: System.Reflection.ConstructorInfo;
begin
InitMetaTypeMap;
Result := _TClass(MetaTypeMap[ATypeHandle]);
if not Assigned(Result) then
begin
save := System.Type.GetTypeFromHandle(ATypeHandle);
t := save;
if not t.IsSubClassOf(TypeOf(_TClass)) then
begin
t := t.GetNestedType('@Meta' + t.name,
BindingFlags.Public or BindingFlags.NonPublic);
end;
if Assigned(t) then
Result := _TClass(t.GetField('@Instance').GetValue(nil))
else
begin// Requested type is not a Delphi class
t := save.BaseType;
if Assigned(t) then
begin// Is it a descendent of a Delphi class?
ancestor := _GetMetaFromHandle(t.TypeHandle);
t := System.Object(ancestor).GetType;
if t.IsSubClassOf(TypeOf(_TClass)) then
begin// yes! descendent of a Delphi class
ctorInfo := t.GetConstructor(System.Type.EmptyTypes);
if Assigned(ctorInfo) then
begin// construct an instance of the Delphi classref
// but set its instancetypehandle to this non-Delphi type
Result := _TClass(ctorInfo.Invoke(nil));
Result.SetInstanceType(ATypeHandle);
end;
end;
end;
if not Assigned(Result) then
Result := _TClass.Create(ATypeHandle);
end;
MetaTypeMap.Add(ATypeHandle, Result);
end;
end;
function _GetMetaFromObject(Obj: TObject): _TClass;
begin
if Obj = nil then
Result := nil
else if Obj is _TClass then
Result := _TClass(Obj)
else
Result := _GetMetaFromHandle(System.Type.GetTypeHandle(Obj));
end;
Хотя доступ к Хэш таблице достаточно быстр, это всетаки не получение адреса VMT из первого поля объекта.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, mister-AK, Вы писали:
MA>>Здравствуйте, Serginio1, Вы писали:
S>>>3. Какую еще дополнительные фунциональность через них можно добавлять, кроме методов (интерфейсы, поля, итд)
MA>>самое неприятное, что поля-переменные добавить не удалось неужели это не реализуемо?
S> Поля и интерфейсы, а также переопределение виртуальных методв сделать нельзя, т.к. на создание экземпляра этого типа уже нельзя никак воздействовать.
вот это совсем никуды не годится
ну... в общем скорее от этого ООП к компонентным моделям бы или вооще — от дотнета подальше
надо было такой механизм, что бы всё, вплоть до типов можно было переопределить... а так — это полумеры инвалидные
пытался TRadioGroup одним свойством доопределить через хэлперы.. значит это невозможно — private поля нужны... наследовать нехоцца...
кому нужен будет мой потомок, который только и отличается от базового, что у него есть BevelInner и BevelOuter???
совсем это никуда не годится
а как же всё делается через ж?... разговор вроде был по поводу доопределения WinForms, что б от message win32 избавиться.... в каком то соседнем топике по .Net?
S> А видимость методов только public.
всё больше разочарований
S> Кстати методы хэлперов на самом деле статические S> Но если наследуешься от этого объекта, то все методы класса хэлпера автоматически прописыватся в классе наследнике
можно подробности... они что перестают быть public class?