2012-03-12 31 views
8

Các biến thể luôn vui vẻ, eh?Làm thế nào để biết một biến thể Delphi là một chuỗi rỗng?

Tôi đang làm việc trên một ứng dụng kế thừa đã được cuối cùng trong D2007 để di chuyển nó đến Delphi XE.

Các biến thể đã thay đổi một chút trong thời gian tạm thời.

dòng mã này:

if (VarType(Value) = varString) and (Value = '') then 
    Exit; 

trở True và thoát trong D2007, nhưng không ở Delphi XE.

Tôi đã thay đổi nó như thế này:

if VarIsStr(Value) and (VarToStr(Value) = '') then 
    Exit; 

Tôi không thuyết phục đây là "tốt nhất" con đường để đi. Đơn vị Biến thể không có một cuộc gọi cụ thể để làm điều này, và tôi chắc chắn nhớ lại đây là một vấn đề cho folks trong quá khứ. Tuy nhiên, một tìm kiếm không tiết lộ chức năng thư viện hoặc bất kỳ cách nào được chấp nhận khác.

Có cách nào "chính xác" hoặc tốt hơn không?

+0

Ngẫu nhiên 'v = ''' là đúng, nếu tôi gán nó một cách rõ ràng cho 'v: = '';' - Tôi đoán là có nhiều hơn một kiểu biến thể chuỗi, có lẽ là B_STR và một cái gì đó khác, và vì vậy so sánh yếu tố không thành công, mặc dù nội dung giống nhau. –

+0

Wont 'nếu VarToStr (Value) = ''' một mình làm công việc? – kobik

+1

@kobik Điều này không thành công, ví dụ, khi 'Giá trị' bằng' Null'. –

Trả lời

3

Cập nhật: String-cụ thể để tránh trường hợp ngoại lệ:

if VarIsStr(Value) and (Length(VarToStr(v))=0) then ... 

UPDATE3: Nếu bạn muốn hiệu suất tốt hơn và ít chất thải bộ nhớ chuỗi đống thử này. Hãy tưởng tượng rằng các chuỗi có chiều dài 64K. Đoạn mã trên thực hiện một VarToStr và phân bổ 64K không gian UnicodeString heap để giữ dữ liệu, chỉ vì vậy chúng ta có thể tìm kiếm terminator nul ở cuối chuỗi cho BSTR, và cho các con trỏ nil cho các kiểu khác.

Đoạn mã dưới đây hơi kỳ quặc trong đó không phổ biến vào đại diện bên trong của các biến thể, nhưng David đã chỉ ra các lỗi và tôi kiểm tra lại nó và nó có vẻ hoạt động. hoặc ngụ ý. Một bài kiểm tra đơn vị cho chú cún này sẽ tốt. Vào một số ngày trong tương lai, nếu các vị thần Delphi RTL quyết định đổi tên đại diện bên trong của các trường cấu trúc Biến thể, thì mã dưới đây sẽ cần được thay đổi.

function VarStrEmpty(v:Variant):Boolean; 
var 
    data:PVarData; 
begin 
    data := FindVarData(V); 
    case data^.VType of 
    varOleStr: 
      result := (data^.VOleStr^=#0); 
    varString: 
      result := (data^.VString=nil); 
    varUString: 
      result := (data^.VUString=nil); 
    else 
     result := false; 
    end; 
end; 
+2

Nick đang cố gắng tránh các ngoại lệ phát sinh khi biến thể không thể bị ép buộc thành một chuỗi. Đó là lý do tại sao anh ta cần kiểm tra đầu tiên và đánh giá ngắn mạch. –

+1

Tôi đang đấu tranh để xem tất cả những gì phức tạp thêm mang lại ở đây. Nó cũng sẽ cung cấp cho một câu trả lời sai lầm cho một OleStr trống tôi nghĩ bởi vì họ được đại diện như là một đơn wchar_t null. Hay tôi đã hiểu sai? Có gì xấu khi so sánh với ''? –

+0

Nó không phải luôn luôn làm việc, trừ khi bạn san bằng nó vào một UnicodeString với VartoString.Để làm cho một tương tự, nó giống như đếm tất cả các đồng xu của bạn từng người một để chắc chắn rằng bạn có BẤT K.. Nó không cần thiết và lãng phí. –

12

VarIsStr là cách hoàn toàn hợp lý để thực hiện. Điều này được triển khai dưới dạng:

function VarTypeIsStr(const AVarType: TVarType): Boolean; 
begin 
    Result := (AVarType = varOleStr) or (AVarType = varString) 
    or (AVarType = varUString); 
end; 

function VarIsStr(const V: Variant): Boolean; 
begin 
    Result := VarTypeIsStr(FindVarData(V)^.VType); 
end; 

Thay đổi bạn thấy, tất nhiên, thực sự là do thay đổi Unicode trong D2009 thay vì thay đổi thành biến thể. Chuỗi của bạn sẽ là varUString, aka UnicodeString. Tất nhiên, VarIsStr cũng chọn AnsiString/varStringWideString/BSTR/varOleStr.

Nếu bạn muốn có một chuyển đổi thực sự trung thành của mã Delphi 2007 của bạn thì bạn sẽ viết:

if (VarType(Value) = varUString) and (Value = '') then 
    Exit; 

Chính xác những gì bạn cần phải làm, chỉ có bạn mới có thể biết, nhưng điều quan trọng là bạn có vào tài khoản cho số mới đến varUString.

0

Các biến thể có thể là Số hoặc Chuỗi.

Có thể có vấn đề khi Biến thể (Số) có giá trị âm (-15).

Ngoài ra dòng bạn

(VarType(Value) = varString) and (Value = '') 

tôi luôn luôn phải đặt ()

((VarType(Value) = varString) and (Value = '')) 
+1

Bạn hiểu nhầm câu hỏi. Số âm không liên quan ở đây. Ngoài ra, điểm thứ hai của bạn về() đơn giản là sai. –

-1
if VarToStrDef(value, '') = '' then 

Liệu các trick cho tôi.

+1

Bạn sẽ mặc định tất cả các trường hợp khi 'giá trị' không phải là một chuỗi thành true. Logic đó không khớp với câu hỏi. –

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