如何在 D5 中实现 VarIsNumeric?

How to implement VarIsNumeric in D5?

我查看了 D2009 源代码,但我仍然不确定如何正确 在 Delphi 5(那里不是 TVarType)。

我现在正在使用这个:

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

这是正确的吗?

测试VarType()返回的值是正确的做法。您只需要确定哪些类型是数字。 Delphi 5 与更高版本的变体支持有很大不同。的确,Delphi6在这方面做出了很大的改变。

Delphi5 系统单元中定义的 var 类型是:

{ Variant type codes (wtypes.h) }
varEmpty    = [=10=]00; { vt_empty       }
varNull     = [=10=]01; { vt_null        }
varSmallint = [=10=]02; { vt_i2          }
varInteger  = [=10=]03; { vt_i4          }
varSingle   = [=10=]04; { vt_r4          }
varDouble   = [=10=]05; { vt_r8          }
varCurrency = [=10=]06; { vt_cy          }
varDate     = [=10=]07; { vt_date        }
varOleStr   = [=10=]08; { vt_bstr        }
varDispatch = [=10=]09; { vt_dispatch    }
varError    = [=10=]0A; { vt_error       }
varBoolean  = [=10=]0B; { vt_bool        }
varVariant  = [=10=]0C; { vt_variant     }
varUnknown  = [=10=]0D; { vt_unknown     }
                     { vt_decimal $e  }
                     { undefined  $f  }
                     { vt_i1       }
varByte     = [=10=]11; { vt_ui1         }
                     { vt_ui2      }
                     { vt_ui4      }
                     { vt_i8       }
{ if adding new items, update varLast, BaseTypeMap and OpTypeMap }
varStrArg   = [=10=]48; { vt_clsid    }
varString   = 00; { Pascal string; not OLE compatible }
varAny      = 01;
varTypeMask = [=10=]FFF;
varArray    = 00;
varByRef    = 00;

现代 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;

现在,现代 Delphi 中的 TVarType 已经没有什么神秘的了。它只是 Word:

的别名
type
  TVarType = Word;

所以你当然可以按照你在问题中提出的方式实施VarIsNumeric。争论的唯一要点是要测试哪些 var 类型。要遵循现代 Delphi,您需要测试这些类型:

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

我已经注释掉了 Delphi 5 RTL 未定义的值。

如果您希望从可能使用其中某些类型的来源接收变体,那么您可能需要定义缺失值并对其进行测试。缺失值是:

varShortInt = [=15=]10; { vt_i1          16 }
varWord     = [=15=]12; { vt_ui2         18 }
varLongWord = [=15=]13; { vt_ui4         19 }
varInt64    = [=15=]14; { vt_i8          20 }
varUInt64   = [=15=]15; { vt_ui8         21 }