2009-11-18 40 views
5

Có cách nào để xác định loại biến được chuyển làm đối số cho phương thức không? Hãy xem xét các lớp:Delphi: xác định loại thực tế của một generic?

TSomeClass = class 
    procedure AddToList<T: TDataType; U: TListClass<T>>(Element: T; List: U); 
end; 

với việc thực hiện phương pháp

procedure TSomeClass.AddToList<T, U>(Element: T; List: U); 
begin 
    if Element is TInt then 
    List.AddElement(TInt.Create(XXX)) 
    else if Element is TString then 
    List.AddElement(TString.Create(YYY)); 
end; 

nơi TInt.Create() và TString.Create() có bộ khác nhau của các đối số, tuy nhiên, cả hai đều kế thừa từ TDataType.

Bây giờ, tôi biết không thể sử dụng is -operator như thế này, nhưng có một giải pháp thay thế hợp pháp làm những gì tôi yêu cầu ở đây không?

+4

Nếu điều đầu tiên bạn làm trong mã chung là viết mã loại cụ thể cho mỗi giá trị chung chung có thể, thì bạn không viết mã chung nữa. Đây không phải là nơi để sử dụng Generics. –

+2

Cảm ơn Rob đầu vào. Khi tôi đăng câu hỏi tại SO (và các địa điểm khác), tôi thường đưa ra các phiên bản ngu ngốc của mã thực sự của mình. Việc giải nén bản chất của vấn đề là, theo kinh nghiệm của tôi, hữu ích hơn việc trình bày mã thực tế - mã thường phức tạp hơn nhiều. Vì vậy, hãy xem xét mã trên một minh họa về một vấn đề lớn hơn. Btw: Tôi muốn đọc về một giải pháp thay thế cho mã trên. Vui lòng xem câu hỏi tiếp theo của tôi: http://stackoverflow.com/questions/1761487/delphi-generics-and-is-operator-problem. Tôi đang mong chờ bất kỳ đầu vào nào trên bài đăng đó! :) – conciliator

Trả lời

5

Không thể sử dụng là nhà điều hành ở đây là sự cố đã biết nhưng có cách giải quyết khá đơn giản.

if TObject(Element) is TInt then 
    List.AddElement(TInt.Create(XXX)) 

Ngoài ra, vì loại chung là một phần của lớp và được biết đến lúc biên dịch, bạn có thể nên chuyển đổi mã của mình tốt hơn. Tạo hai lớp chung khác nhau, một trong số đó chấp nhận TInt làm tham số <T> và một trong số đó chấp nhận TString. Đặt chức năng kiểu cụ thể vào chúng ở cấp độ đó và đưa chúng xuống từ tổ tiên chung cho chức năng được chia sẻ.

+0

Cảm ơn Mason! Tuy nhiên, tôi nhận được lỗi "lỗi định dạng không hợp lệ E2089". Bạn có biết tại sao? Và tôi có thể đã không được rõ ràng trong bài viết cuối cùng của tôi, nhưng TInt và TString cả hai xuống từ TDataType, nhưng chúng khác nhau ở mức TInt và TString (đặc biệt là các nhà xây dựng của họ). Đó là những gì bạn có nghĩa là, phải không? Dù sao - ràng buộc được đặt là "gần" TInt và TString nhất có thể để đảm bảo chức năng tối ưu. – conciliator

+0

Bạn nhận được lỗi trên đường nào? Tôi không có mã của bạn để kiểm tra trên, nhưng tôi đã viết một bài kiểm tra đơn giản và đúc TObject hoạt động tốt cho tôi ... –

+0

Trong bài viết ban đầu của tôi, tôi đã làm việc với một thiết kế phức tạp hơn, nhưng đã đưa ra ví dụ như trình bày ở trên, bởi vì nó nắm bắt được vấn đề thiết yếu mà tôi đang gặp phải. Vì vậy, khi được yêu cầu cho toàn bộ nguồn, tôi đã phải mã hóa nó từ "đầu". Có vẻ hơi khác một chút, nhưng tôi vẫn gặp vấn đề về typecast. Tôi có nên đăng câu hỏi đó dưới dạng câu hỏi riêng hoặc câu trả lời cho bài đăng của bạn không? – conciliator

4

Câu hỏi này tôi hỏi một số thời gian trước đây

Conditional behaviour based on concrete type for generic class

thể được quan tâm, đặc biệt là nếu bạn muốn sử dụng không chỉ TObject con cháu mà còn loại nguyên thủy trong điều kiện của bạn.

+1

+1 Bạn đã lưu ngày của tôi khi tôi cần câu trả lời được liên kết để bật các chức năng chuyển đổi chung cho các loại được liệt kê. –

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