初学者的问题: with (明白了! with 无非的范围的搜索优先作用。) (10分)

  • 主题发起人 拾荒者
  • 开始时间

拾荒者

Unregistered / Unconfirmed
GUEST, unregistred user!
明白了! with 无非起了范围搜索优先作用。
如 with TestA,TestB do
变量或成员的搜索优先级别会是:
先搜 TestA,如果没有,再是 TestB ,最后才是默认例程。 :) (吐了一口气。)

原问题:

这是《DELPHI 深度历险》的例:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

type
// ﹚竡???癟?挡篶
TWowMessage = record
Msg: Cardinal;
WowStr: string;
end;

TDog = class
private
// Μ?癟? 100 ?, 穦㊣??よ猭
procedure Wow(var message: TWowMessage)
message 100;
end;

{ TDog }

procedure TDog.Wow(var message: TWowMessage);
begin
// ?沮癟?挡篶?戈?, ??羘
ShowMessage(message.WowStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Msg: TWowMessage;
begin
[h1][red]with TDog.Create do[/red][/h1]
try
// ??﹚癟?挡篶ず甧
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
// だ??癟?
Dispatch(Msg);
finally
Free;
end;
end;
end.

我不明白的就是为何书中这段代码可编译通过。好像与 Object Pascal 语法书中所说
不相符呀?
按我理解应该
with TDog.Create do
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dispatch(Msg);
finally
Free;
end;
end;
也应该等同于
var
Dog: TDog;
begin
Dog := TDog.Create;
with Dog do
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dispatch(Msg);
finally
Free;
end;
end;
吧? 那么为何 Dog. 却能不冠于
Msg.Msg := 100

Msg.WowStr := 'Ouch !!';
之前呢?按理应等同 Dog.Msg.Msg := 100
呀?
 
var
msg:Twowmessage;
begin
with tdog.create do
with twowmessage do
begin
msg:=100;
msg.wowstr:='wow';
end;
dispatch(msg);
end;
 
with TDog.Create do
try
// ??﹚癟?挡篶ず甧
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
// だ??癟?
Dispatch(Msg);
finally
Free;
end;
end;
等同于
var
Dog: TDog;
begin
Dog := TDog.Create(nil);
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dog.Dispatch(Msg);
finally
Dog.Free;
end;
end;
明了了吧?
 
with TDog.Create do
try
// ??﹚癟?挡篶ず甧
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
// だ??癟?
Dispatch(Msg);
finally
Free;
end;
end;
等同于
var
Dog: TDog;
begin
Dog := TDog.Create(nil);
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dog.Dispatch(Msg);
finally
Dog.Free;
end;
end;
 
在With Object do
begin
.........
end
语句中,如果所引用的Property或是Mathod不属于Object,可以指定相应的对象。此时,
在Delphi中是可以编译通过的。你还可以在begin...end间使用:Object.Property。
这可能是为了使用上的方便。
 
我是初学者,比较笨。:) 明白了一半。

with TDog.Create do
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dispatch(Msg);
finally
Free;
end;
end;
也应该等同于
var
Dog: TDog;
begin
Dog := TDog.Create(nil);
[red]with Dog do[/red]
try
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
Dispatch(Msg);
finally
Free;
end;
end;
吧? 那么为何 Dog. 却能不冠于
Msg.Msg := 100

Msg.WowStr := 'Ouch !!';
之前呢?按理应等同 Dog.Msg.Msg := 100
呀?
 
在With语句中并不是所有的东东都是With的对象的的成员。就象Msg,他只是一个过程内的局部变量,
所有无论在什么地方(在With语句内也是一样),它前面都不能冠以Dog。所以Dog.Msg.Msg := 100;
这样的语句在语法上是错误的。
通过界定符"."界定的后面部份必须是前面部份的成员,而并不是在语法上的从属关系!
 
aizb:
不是 With 的对象的的成员,Delphi 编译器就会自动忽略,不在它前面 冠以Dog. 这样理解对吗?
 
在With语句中,你可以放入一般的语句,比如
Msg.Msg := 100;
Msg.WowStr := 'Ouch !!';
两句,这两句和Dog在语法上没有任何关系,也就是说用不用With,这两句都是一样的,你不能在Msg前加上Dog.
但是第三句就不一样了Dispatch方法是TObject类的Public成员,TDog没有显示指明父类,则它的父类是TObject,
所以Dispatch也就是TDog的Public成员,在这里因为有了With语句,就可以省略Dog对象界定符,
而如果没有With语句,则你必须在Dispatch方法前加上"Dog.",否则会出现编译不能通过的情况.
当然加了With语句,你也可以在Dispatch前加上"Dog.",在语法上是一样的!
 
感谢 aizb ! 我明白了,果然 “加了With语句,你也可以在Dispatch前加上"Dog.",
在语法上是一样”
 
明白了! with 无非起了范围搜索优先作用。
如 with TestA,TestB do
变量或成员的搜索优先级别会是:
先搜 TestA,如果没有,再是 TestB ,最后才是默认例程。 :) (吐了一口气。)
 
顶部