2015-05-20 2 views
1

Я изучил источники D2009, но все же не уверен, как правильно реализовать функцию VarIsNumeric (варианты) в Delphi 5 (нет TVarType).Как реализовать VarIsNumeric в D5?

Я использую это сейчас:

function VarIsNumeric(const V: Variant): Boolean; 
begin 
    Result := VarType(V) in [varSmallInt, varInteger, varBoolean, 
          varByte, 
          varSingle, 
          varDouble]; 
end; 

Правильно ли это?

+0

Не был ли varShortint, varWord, varLongWord и varCurrency частью типа варианта D5? –

+0

Это зависит от того, что вы считаете числовым. Почему вы выбрали тех и отвергли других? Посмотрите на каждый varXXX и сделайте суждение. Если вы хотите, чтобы определение соответствовало D2009 rtl, используйте его как свой шаблон. Похоже, у вас есть все, что вам нужно для решения проблемы самостоятельно. –

+0

@DavidHeffernan, в XE8, varDate не считается числовым значением, например. –

ответ

5

Тестирование значения, возвращаемого VarType(), является правильным подходом. Вам просто нужно решить, какие типы являются числовыми. Delphi 5 имеет очень разную поддержку вариантов из более поздних версий. Действительно, Delphi 6 внес большие изменения в эту область.

Значение переменной типа определяют в системном блоке Delphi 5 являются:

{ Variant type codes (wtypes.h) } 
varEmpty = $0000; { vt_empty  } 
varNull  = $0001; { vt_null  } 
varSmallint = $0002; { vt_i2   } 
varInteger = $0003; { vt_i4   } 
varSingle = $0004; { vt_r4   } 
varDouble = $0005; { vt_r8   } 
varCurrency = $0006; { vt_cy   } 
varDate  = $0007; { vt_date  } 
varOleStr = $0008; { vt_bstr  } 
varDispatch = $0009; { vt_dispatch } 
varError = $000A; { vt_error  } 
varBoolean = $000B; { vt_bool  } 
varVariant = $000C; { vt_variant  } 
varUnknown = $000D; { vt_unknown  } 
        { vt_decimal $e } 
        { undefined $f } 
        { vt_i1  $10 } 
varByte  = $0011; { vt_ui1   } 
        { vt_ui2  $12 } 
        { vt_ui4  $13 } 
        { vt_i8  $14 } 
{ if adding new items, update varLast, BaseTypeMap and OpTypeMap } 
varStrArg = $0048; { vt_clsid } 
varString = $0100; { Pascal string; not OLE compatible } 
varAny  = $0101; 
varTypeMask = $0FFF; 
varArray = $2000; 
varByRef = $4000; 

В современном Delphi VarIsNumeric реализован как

Result := VarTypeIsOrdinal(AVarType) or VarTypeIsFloat(AVarType); 

и в свою очередь

function VarTypeIsOrdinal(const AVarType: TVarType): Boolean; 
begin 
    Result := AVarType in [varSmallInt, varInteger, varBoolean, varShortInt, 
         varByte, varWord, varLongWord, varInt64, varUInt64]; 
end; 

function VarTypeIsFloat(const AVarType: TVarType): Boolean; 
begin 
    Result := AVarType in [varSingle, varDouble, varCurrency]; 
end; 

Теперь есть ничего мистического о TVarType в современном Delphi. Это просто псевдоним Word:

type 
    TVarType = Word; 

Таким образом, вы можете, конечно, реализовать VarIsNumeric в порядке, вы предлагаете в этом вопросе. Единственный момент для обсуждения - это те типы var, которые нужно тестировать. Для того, чтобы следовать современной Delphi, вы бы проверить для этих типов:

varSmallInt 
varInteger 
varBoolean 
// varShortInt 
varByte 
// varWord 
// varLongWord 
// varInt64 
// varUInt64 
varSingle 
varDouble 
varCurrency 

Я закомментирована значение, которые не определены в Delphi 5 RTL.

Если вы ожидали получить варианты из источников, которые могут использовать некоторые из этих типов, тогда вам может понадобиться определить отсутствующие значения и проверить их. Недопустимые значения:

varShortInt = $0010; { vt_i1   16 } 
varWord  = $0012; { vt_ui2   18 } 
varLongWord = $0013; { vt_ui4   19 } 
varInt64 = $0014; { vt_i8   20 } 
varUInt64 = $0015; { vt_ui8   21 } 
+2

Спасибо @David. Отличный ответ! – zig

Смежные вопросы