나는이 원자 낙관적 초기화 클래스가 함께 제네릭을 결합 :다른 제약
type
Atomic<T: IInterface> = class
type TFactory = reference to function: T;
class function Initialize(var storage: T; factory: TFactory): T;
end;
class function Atomic<T>.Initialize(var storage: T; factory: TFactory): T;
var
tmpIntf: T;
begin
if not assigned(storage) then begin
tmpIntf := factory();
if InterlockedCompareExchangePointer(PPointer(@storage)^, PPointer(@tmpIntf)^, nil) = nil then
PPointer(@tmpIntf)^ := nil;
end;
Result := storage;
end;
가 지금은 개체에 대한 동일한 패턴을 구현하고자합니다.
type
Atomic<T: class> = class
type TFactory = reference to function: T;
class function Initialize(var storage: T; factory: TFactory): T;
end;
class function Atomic<T>.Initialize(var storage: T; factory: TFactory): T;
var
tmpIntf: T;
begin
if not assigned(storage) then begin
tmpIntf := factory();
if InterlockedCompareExchangePointer(PPointer(@storage)^, PPointer(@tmpIntf)^, nil) = nil then
tmpIntf.Free;
end;
Result := storage;
end;
두 개의 클래스로 나눌 수 있지만 두 개의 이니셜 라이저를 동일한 우산 아래에 두는 것이 좋습니다. IOW, 나는 이것을 이상적으로 사용하는 것이 이상적입니다.
var
o: TObject;
i: IInterface;
Atomic<TObject>.Initialize(o, CreateObject);
Atomic<IInterface>.Initialize(i, CreateInterface);
나는 이것을위한 좋은 해결책을 찾을 수 없습니다. 내가 가진 유일한 아이디어는 클래스를 Atomic<T>
(제약없이)으로 선언 한 다음 런타임에 T의 RTTI를 확인하고 그에 따라 진행하는 것입니다.
나는이 아이디어를별로 좋아하지 않으며 나는 더 나은 접근법을 찾고있다.
감사합니다. – gabr
환영합니다. @ 가브리, 도와 드릴 수있어서 기쁩니다! –