Delphi:为什么类变量会影响方法的结果?

use*_*155 5 delphi

这是我的代码的完全简化,但即使如此,当类var ID_COUNTER存在时它也不起作用,在这段代码中我不使用类var,但是在我的实际代码中是的,但只是这个类的存在变量使's'的结果不同.这是我见过的最奇怪的事情.

这是一个简化,但仍然不起作用,一个单位在75行.

 unit Umain;
 interface
 uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,     Vcl.StdCtrls,XMLIntf,XmlDoc,IOUtils,XMLDom,System.Generics.Collections;

type
  TStore = class
  public
   class var ID_COUNTER: Integer;
   MainNode: IDomNode;
  constructor create(node:IDomNode);
   function getNode():IDomNode;
 end;
TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
 FMain: TStore;
   function Recursive(node:IDomNode):TStore;

 end;

 var
    Form1: TForm1;

 implementation

 {$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Doc:IXMLDocument;
  content: WideString;
  html: IDomNode;
  s: String;
 begin
    Doc := TXMLDocument.Create(Application);
    Doc.LoadFromFile('C:\temp\example.xml');
    Doc.Active := true;
    html := Doc.DOMDocument.getElementsByTagName('html').item[0];
    FMain := Recursive(html);
    s := FMain.getNode().nodeName;
 end;

 function TForm1.Recursive(node: IDOMNode):TStore;
 var
   i: Integer;
   store: TStore;
  nodeName,nodeValue:String;
 begin
   store := TStore.create(node);

  if(not node.hasChildNodes)then
    Exit(store);

   for i := 0 to node.childNodes.length-1 do
   begin
     Recursive(node.childNodes.item[i]);
   end;

  Exit(store);
end;
constructor TStore.create(node: IDOMNode);
begin
  self.MainNode := node;
end;
function TStore.getNode:IDomNode;
begin
  Result := self.MainNode;
end;

end.
Run Code Online (Sandbox Code Playgroud)

一些说明:

example.xml只是一个简单的HTML文档.当ID_COUNTER存在时,一切都被打破,如果被注释,一切都好.它发生在这里和我真实的广泛项目中.

Rud*_*uis 17

问题是,语法,class var引入一类场,而不是一个单一的类领域,这意味着,如果你使用class var,在同样的知名度节中的所有以下字段声明将类变量太多.所以现在,也MainNode成为一个类变量,这可能会导致你遇到的问题.重新格式化代码可以更清楚地显示:

public
  class var 
    ID_COUNT: Integer;
    MainNode: IDomNode;
  constructor Create(... etc.
Run Code Online (Sandbox Code Playgroud)

你的选择是:

  • ID_COUNT向下移动一行:

    public
      MainNode: IDomNode;
      class var ID_COUNTER: Integer;
      constructor Create(... etc.
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建一个特殊部分MainNode:

    public
      class var ID_COUNTER: Integer;
    public
      MainNode: IDomNode;
      constructor Create(... etc.
    
    Run Code Online (Sandbox Code Playgroud)
  • 前缀MainNodevar关键字(同样,它引入一个,特别是当前可见性部分中的实例字段块):

    public
      class var 
        ID_COUNTER: Integer;
        // any other class variables
      var 
        MainNode: IDomNode;
        // any other instance variables
      constructor Create(... etc.
    
    Run Code Online (Sandbox Code Playgroud)

  • 你也可以使用普通的`var`来引入实例var.好点.+1 (3认同)