处理具有不明确参数的重载函数

时间:2013-01-05 07:53:58

标签: delphi delphi-xe

拿这个小示例类(不是我的真实代码,但它暴露了问题):

Convert = class(TObject)
  public
    class function ToString(value: Double): String; overload;
    class function ToString(value: TDateTime): String; overload;
  end;

在您尝试使用DoubleTDateTime函数As之前,它会正常编译 在:

var
  d: Double;
begin
  d := 99.99;
  ShowMessage(Convert.ToString(d));

您将收到此编译错误:对'ToString'进行不明确的重载调用。 问题归结为TDateTimeDouble

的类型

我的问题:你如何处理这类问题?

编辑 - 我不是在寻找给出

示例的解决方案

到目前为止,我找到了3个解决方案:

  • 重命名2个功能之一
  • 将“Dummy”参数添加到2个函数之一
  • 将参数更改为Var类型,这样做的缺点是我不能再使用常量
  • 调用此函数

还有其他解决方案吗?

3 个答案:

答案 0 :(得分:14)

重载方法非常有效。然而,一旦有一丝模糊,他们就会成为一种责任。一个很好的例子是XE3中引入的新TStream重载。陷入编译器选择您不期望的重载的陷阱并不难。至少在你的代码中编译器停止了。从那个意义上说你很幸运。

因此,在您的情况下,我的建议是放弃超载。在方法名称中表示不同的输入类型。是的,它有点冗长,但你不会犯任何错误,你的代码会编译!

答案 1 :(得分:5)

您发布的示例在XE中编译并执行正常。

在评论中,您可以改为提供此示例:

ShowMessage( Convert.ToString( 99.99 ));  // <- gives compiler error 2251

在这种特殊情况下,解决方案是明确定义类型(我认为):

ShowMessage( Convert.ToString( Double(99.99) )); // <- E2089, Invalid Typecast

查看文档:

  
    

为规则不允许的类型转换发出此错误消息。允许以下类型的演员阵容:

         
        
  • 另一个序数或指针类型的序数或指针类型
  •     
  • 字符串,字符串,字符数组或字符串
  •     
  • 变体的序数,真实,字符串或变体
  •     
  • 序数,真实,字符串或变体的变体
  •     
  • 对任何类型相同尺寸的变量引用。
  •     
  

因此,要明确告诉编译器选择Double重载函数:

ShowMessage( Convert.ToString( Double(Variant(99.99)))); // Ok

或许有点复杂。但对于其他重载函数,它更简单:

ShowMessage( Convert.ToString( EncodeDate(2013,1,5));

  

更新


要使其成为适用于所有类的通用解决方案,请考虑添加类函数以解决模糊类型。

Convert = Class(TObject)
  ...
  class function AsDouble( value: Double) : Double; inline; static;
  class function AsTDateTime( value: TDateTime) : TDateTime; inline; static;
end;

class function Convert.AsDouble(value: Double): Double;
begin
  Result := Value;
end;
class function Convert.AsDateTime(value: TDateTime): TDateTime;
begin
  Result := Value;
end;

现在您可以使用常量调用重载的类函数:

ShowMessage( Convert.ToString( Convert.AsDouble(99.99)));   

答案 2 :(得分:1)

如何折叠它?:

class function Convert.ToString(value: Variant): String;
begin
   Result := VarToStr(Value);
end;