cevap parlak: Burada
class function TPersistGeneric<T>.Init: T;
var
o : TXPersistent; // root class
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkClass : begin
// xpcreate returns txpersistent, a root class of T
o := XPCreate(GetTypeName(TypeInfo(T))); // has a listed of registered classes
Result := TTypeCast.DynamicCast<TXPersistent, T>(o);
end;
else
result := Default(T);
end;
sınıftır. Delphi'de jeneriklerin kullanılmasına gerçekten yardımcı oldu. Lütfen, lütfen DynamicCast'ın biraz karmaşık olup olmadığını merak edince Andreas'ı affedin. Lütfen yanılıyorsam beni düzeltin ama aşağıdakiler biraz daha özlü, güvenli, hızlı (dize karşılaştırması yok) ve hala işlevsel olarak olmalıdır.
Yaptığım tek şey, derleyicinin biraz iş yapmasına izin vermek için DynamicCast türü paramları üzerindeki sınıf kısıtlamasını kullanmasıdır (orijinal olarak her zaman sınıf dışı parametreler hariç) ve sonra TObject.InheritsFrom'u kullanın. tür uyumluluğunu kontrol etmek için işlev. Ben eşleşen f aile trol yerde noktası cevapsız sürece de oldukça yararlı bir TryCast fonksiyonunun fikrini buldum
(zaten benim için ortak bir görev!)
Bu elbette adlar ... bu tip isimlerin farklı kapsamlardaki uyumlu olmayan sınıflar için eşleşebileceği düşünüldüğünde IMHO biraz tehlikelidir.
Her neyse, işte kodum (Delphi XE3 ... için çalışır. D2009, TryCast'in uyumlu sürümü aşağıdaki gibidir). D2009 versiyonunu Söz verdiğimiz gibi
type
TTypeCast = class
public
// ReinterpretCast does a hard type cast
class function ReinterpretCast<ReturnT>(const Value): ReturnT;
// StaticCast does a hard type cast but requires an input type
class function StaticCast<T, ReturnT>(const Value: T): ReturnT;
// Attempt a dynamic cast, returning True if successful
class function TryCast<T, ReturnT: class>(const Value: T; out Return: ReturnT): Boolean;
// DynamicCast is like the as-operator. It checks if the object can be typecasted
class function DynamicCast<T, ReturnT: class>(const Value: T): ReturnT;
end;
implementation
uses
System.SysUtils;
class function TTypeCast.ReinterpretCast<ReturnT>(const Value): ReturnT;
begin
Result := ReturnT(Value);
end;
class function TTypeCast.StaticCast<T, ReturnT>(const Value: T): ReturnT;
begin
Result := ReinterpretCast<ReturnT>(Value);
end;
class function TTypeCast.TryCast<T, ReturnT>(const Value: T; out Return: ReturnT): Boolean;
begin
Result := (not Assigned(Value)) or Value.InheritsFrom(ReturnT);
if Result then
Return := ReinterpretCast<ReturnT>(Value);
end;
class function TTypeCast.DynamicCast<T, ReturnT>(const Value: T): ReturnT;
begin
if not TryCast<T, ReturnT>(Value, Result) then
//Value will definately be assigned is TryCast returns false
raise EInvalidCast.CreateFmt('Invalid class typecast from %s(%s) to %s',
[T.ClassName, Value.ClassName, ReturnT.ClassName]);
end;
(ReturnT sınıfına almak için bazı küçük bir çaba gerekir).
class function TTypeCast.TryCast<T, ReturnT>(const Value: T; out Return: ReturnT): Boolean;
var
LReturnTypeInfo: PTypeInfo;
LReturnClass: TClass;
begin
Result := True;
if not Assigned(Value) then
Return := Default(ReturnT)
else
begin
LReturnTypeInfo := TypeInfo(ReturnT);
LReturnClass := GetTypeData(LReturnTypeInfo).ClassType;
if Value.InheritsFrom(LReturnClass) then
Return := ReinterpretCast<ReturnT>(Value)
else
Result := False;
end;
end;
Çok kötü Ben bunu favori bir yanıt olarak işaretleyemem ... – gabr
Bu daha büyük! – kabstergo