如何在D5中实现VarIsNumeric?

zig*_*zig 1 delphi delphi-5

我已经查看了D2009的来源,但我仍然不确定如何在Delphi 5中正确实现VarIsNumeric(Variants)函数(没有TVarType).

我现在正在使用它:

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

它是否正确?

Dav*_*nan 5

测试返回的值VarType()是正确的方法.您只需要确定哪些类型是数字.Delphi 5与以后的版本具有非常不同的变体支持.实际上,Delphi 6在这方面做出了很大的改变.

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

{ 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;
Run Code Online (Sandbox Code Playgroud)

在现代德尔福VarIsNumeric实现为

Result := VarTypeIsOrdinal(AVarType) or VarTypeIsFloat(AVarType);
Run Code Online (Sandbox Code Playgroud)

而反过来

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;
Run Code Online (Sandbox Code Playgroud)

现在,TVarType在现代德尔福中没有什么神秘的东西.它只是一个别名Word:

type
  TVarType = Word;
Run Code Online (Sandbox Code Playgroud)

所以你当然可以VarIsNumeric按照你在问题中提出的方式实施.辩论的唯一要点是要测试的var类型.要遵循现代Delphi,您将测试以下类型:

varSmallInt
varInteger
varBoolean
// varShortInt
varByte
// varWord
// varLongWord
// varInt64
// varUInt64
varSingle
varDouble
varCurrency
Run Code Online (Sandbox Code Playgroud)

我已经注释掉了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 }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@David.很棒的答案! (2认同)