2011-10-25 49 views
6

đây là một đoạn hiển thị những gì tôi đang cố gắng để đạt được:Giá trị chuyển đổi loại <T> thành Biến thể, có thể không?

type 
    TMyObject<T> = class (TObject) 
    function GetVarType(Value: T): TVarType; 
    end; 


function TMyObject<T>.GetVarType(Value: T): TVarType; 
var 
    TmpValue: Variant; 
begin 
    TmpValue := Variant(Value); //Invalid typecast 
    Result := VarType(TmpValue); 
end; 

Tôi biết rằng apporach trên với định kiểu là ngây thơ nhưng tôi hy vọng bạn sẽ có được ý tưởng. Tôi muốn thay thế nó bằng một số cơ chế chuyển đổi.

TMyObject sẽ luôn có loại đơn giản như Số nguyên, Chuỗi, Đơn, Đôi.

Mục đích của chuyển đổi như vậy là hàm VarType cung cấp cho tôi hằng số nguyên cho từng loại đơn giản mà tôi có thể lưu trữ ở một nơi khác.

Tôi muốn biết liệu có thể chuyển đổi như vậy không?

Cảm ơn thời gian của bạn.

Trả lời

6

Bạn có thể sử dụng RTTI để nhận được thông tin này, chỉ cần kiểm tra giá trị của tài sản TTypeInfo.Kind:

Kiểm tra này mẫu mã

{$APPTYPE CONSOLE} 

uses 
    TypInfo, 
    Variants, 
    Generics.Collections, 
    SysUtils; 

type 
    TMyObject<T> = class (TObject) 
    function GetVarType(Value: T): TVarType; 
    end; 


function TMyObject<T>.GetVarType(Value: T): TVarType; 
begin 
    Case PTypeInfo(TypeInfo(T))^.Kind of 
    tkInteger : Result:=varInteger; 
    tkFloat : Result:=varDouble; 
    tkString : Result:=varString; 
    tkUString : Result:=varUString; 
    //add more types here 
    End; 
end; 

Var 
    LObj : TMyObject<Integer>; 
begin 
    try 
    Writeln(VarTypeAsText(TMyObject<Integer>.Create.GetVarType(5))); 
    Writeln(VarTypeAsText(TMyObject<String>.Create.GetVarType('Test'))); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

này sẽ trở lại

Integer 
UnicodeString 
1

Tôi không thể thấy làm thế nào nó có thể làm được điều này với Generics. Trình biên dịch cần phải biết rằng một thể hiện kiểu T có thể được gán cho một Variant cho bất kỳ T có thể có. Không có cách nào để bạn có thể nói rằng trình biên dịch đó là có thể.

Nếu đây là các mẫu như trong C++ thì nó sẽ không quan trọng.

+0

+1, tôi ao ước C++ mẫu trong Delphi ... –

+0

@seth Tôi không biết bạn là một người sử dụng delphi Tôi luôn luôn có bạn xuống như một niềng răng xoăn kinda guy –

+1

Thông thường nhưng không độc quyền.Tôi sử dụng Delphi như là một phiên bản tạo ra có thể thực thi bản địa của C# (không thể đứng không –

1

Thanks guys cho câu trả lời của bạn:

Như @RRUZ đã cho biết đó là khả năng le (Tôi có nghĩa là không nghiêm ngặt assigment nhưng giải nén các loại dữ liệu). Tôi đã làm việc một mình trong khi chờ đợi bất kỳ câu trả lời nào và đã tìm ra một giải pháp chung chung hơn.

Vì vậy, tôi positing nó ở đây:

type 
    TMyObject<T> = class (TObject) 
    function GetVarType(Value: T): TVarType; 
    end; 


function TMyObject<T>.GetVarType(Value: T): TVarType; 
begin 
    Result := GetTypeData(TypeInfo(T)).varType; 
end; 

Một lần nữa cảm ơn!

+1

Không cần phải vượt qua Giá trị, bạn có thể đọc trực tiếp từ T. –

+0

Có bất kỳ dấu hiệu nào cho thấy 'varType' có chứa giá trị hợp lệ khi' TypeInfo (T) hay không. Loại' là n't 'tkDynArray'? Hoặc số nguyên được lưu trữ trong 'varType' thực sự là một giá trị' TVarType', vì mảng động có thể chứa những thứ mà 'Biến thể' không thể? Tôi không nghĩ rằng hoặc là nhất thiết phải đúng sự thật. –

+0

@RobKennedy Tôi sợ bạn có quyền. Tôi không hiểu tại sao nó không hoạt động như mong đợi.Đó là một sự xấu hổ ... – Wodzu

7

Nó có thể giải quyết được trong Delphis với RTTI nâng cao (2010 và mới hơn). Quá xấu bạn bị giới hạn đến 2009 :(

function TMyObject<T>.GetVarType(Value: T): TVarType; 
begin 
    Result := VarType(TValue.From<T>(Value).AsVariant); 
end; 

này chỉ hoạt động với nhiều loại đơn giản nhưng đó là một hạn chế quy định trong câu hỏi.

+0

Cảm ơn @gabr nó sẽ chắc chắn hữu ích khi tôi chuyển sang D2010 :) – Wodzu

Các vấn đề liên quan