एंड्रियास से जवाब ऊपर शानदार है:
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;
यहाँ वर्ग है। यह वास्तव में डेल्फी में जेनेरिक के उपयोग में मेरी मदद करता है। कृपया मुझे एंड्रियास को क्षमा करें क्योंकि मुझे आश्चर्य है कि डायनामिककास्ट थोड़ा जटिल है या नहीं। अगर मैं गलत हूं तो कृपया मुझे सही करें, लेकिन निम्नलिखित थोड़ा संक्षिप्त, सुरक्षित, तेज़ (कोई स्ट्रिंग तुलना नहीं) होना चाहिए और अभी भी कार्यात्मक होना चाहिए।
वास्तव में मैंने जो कुछ किया है, वह गतिशील कैस्ट प्रकार पैरा पर क्लास बाधा का उपयोग करता है ताकि संकलक को कुछ काम करने की अनुमति मिल सके (जैसे मूल हमेशा गैर-वर्ग पैरामीटर को छोड़कर) और फिर TObject.InheritsFrom का उपयोग करें प्रकार संगतता की जांच करने के लिए समारोह।
मैं भी एक TryCast समारोह काफी उपयोगी करने के विचार मिल गया है (यह मेरे लिए एक आम कार्य है वैसे भी!)
इस कोर्स की है, जब तक मैं मिलान के लिए वर्ग के माता पिता trawling में कहीं बिंदु नहीं छूटा है नाम ... जो आईएमएचओ थोड़ा खतरनाक है, क्योंकि टाइप नाम अलग-अलग क्षेत्रों में गैर संगत कक्षाओं के लिए मेल खाते हैं।
वैसे भी, मेरा कोड है (डेल्फी XE3 के लिए काम करता है ... TryCast के D2009 संगत संस्करण के बाद निम्नानुसार है)।
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;
जैसा कि डी 200 9 संस्करण का वादा किया गया था (रिटर्नटी के वर्ग में जाने के लिए कुछ छोटे प्रयासों की आवश्यकता है)।
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;
बहुत बुरा मैं इसे पसंदीदा उत्तर के रूप में चिह्नित नहीं कर सकता ... – gabr
यह अधिक है! – kabstergo