【问题标题】:getting "E2197 Constant object cannot be passed as var parameter" when passing var parameter传递 var 参数时得到“E2197 常量对象不能作为 var 参数传递”
【发布时间】:2011-03-30 11:47:03
【问题描述】:

这段代码运行良好:

procedure TForm2.Timer1Timer(Sender: TObject);
var
  Text: string;
begin  SetLength (Text,555);
  GetWindowText (getforegroundwindow, PChar (Text),555);
  Form2.gtListBox1.Items.Add (
    IntToStr (getforegroundwindow) + ': ' + Text);
end;

但是当我放的时候

var
  Text: string;

从 Timer1Timer 事件处理程序到 单位实现部分或单位 var 部分中的“文本:字符串”我得到错误:E2197 常量对象不能作为 var 参数传递
根据文档:

当您 尝试将常量作为 var 或 out 发送 函数或过程的参数。

但我没有将文本声明为常量,那么为什么会出现此错误?
编辑:@mason Wheeler:我不明白为什么会这样:

implementation
{$R *.dfm}
 var 
 char :integer;//first of all why does delphi let me declare variable that is also a type name
procedure TForm2.Button1Click(Sender: TObject);
begin
char:=11; 
showmessage(IntToStr(char));
end;

我的第一个代码不起作用,因为我将文本声明为字符串,你说:''编译器可能认为它是对类型的引用,而不是对变量的引用''而不是编译器为什么不认为它是对类型的引用而不是这种情况下的变量?我很困惑
Edit2: 我现在明白出了什么问题,但仍然有 1 个困惑我没有使用 with 语句,那么为什么 delphi 会像对待我一样对待使用:

 with
      form1 do
       text := 'blahblahblah';

这在 delphi 部分是错误的,我的意思是 delphi 不应该让我们做 text := 'blah'form1.text := blah;with form1 do text := 'blah'; 我是否需要打开/关闭一些编译器设置我正在使用 delphi 2010 没有任何ide专家

【问题讨论】:

  • 对于每个方法体,您可以想象在函数周围有一个with Self do 块,除了Self 的成员不会像在真正的with 块中那样隐藏局部变量。根据经验,如果您在表单自己的方法中使用 Delphi 生成的全局表单变量,那么您做错了。

标签: delphi error-handling


【解决方案1】:

实际上如果你在实现部分声明Text并在Timer1Timer(Sender: TObject)中使用它,编译器会将Text视为Form1.Text

将文本名称更改为 sText 即可。

编辑 1:

因为像Form1.Char 这样的表单没有属性/字段。

【讨论】:

  • 当我在单元的 var 部分声明它时,编译器仍然认为它是 Form1.Text
  • 如果你在Timer1Timer(Sender: TObject)中声明它,那么编译器将把它当作Text(字符串)而不是Form1.Text,因为它是在定时器方法的范围内声明的
  • Timer 方法之外的任何内容,都将被视为 Form1.Text
  • Omair,在您的类的祖先中声明的 Text 属性的范围比您在函数外部声明的 Text 变量具有更近的范围,但是 比你在函数内部声明的范围更远。编译器绑定到最接近的东西。您可以通过限定名称来提示您想要什么。说Self.Text 表示属性,或UnitName.Text 表示全局变量,或System.Text 表示类型。
  • @Omair。范围,范围,范围!当你在一个对象的方法中时,你对Self有一个隐式作用域,所以如果Text是为TForm1类定义的,在任何TForm1方法中,Text将解析为Self.Text(即你的Form1.Text),除非它被更局部的作用域所掩盖,例如局部变量Textwith
【解决方案2】:

这可能是名称混淆。 “文本”也是一个类型名称,一种传统的文本文件类型。因此,如果您在不同的范围内声明变量,编译器可能会认为它是对类型的引用,而不是对变量的引用。尝试将其命名为其他名称,它应该可以工作。

【讨论】:

  • @Jeroen,Bharat 无法将此标记为已接受,因为这不是他的问题。此外,正如 Bharat 在他的回答中所建议的那样,名称混淆不是 System.Text 类型而是 TForm.Text 属性。
  • @Omair:是的,Bharat 是对的。这是一个名称混淆,但我弄错了 what 它正在混淆。我不知道 TForm 实际上有一个 Text 属性。我以为它使用了字幕。事实证明,两者都在 TControl 上声明了 protected 并且都解决了相同的问题。
【解决方案3】:

关于您的编辑#2:

这是面向对象编程的标准约定。当您为对象编写方法时,代码被隐式解释为在对象的范围内。换句话说,每个对象方法都可以被认为是在一个隐藏的with self do 块内。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2015-02-14
    相关资源
    最近更新 更多