Me关键字在.NET中的使用(转)
2024-07-10 13:02:25
供稿:网友
me关键字在.net中的使用
www.yescnet.com cnet中文网
me 函数大家都很熟了,在vb6中me只能应用于窗体,但在.net中就没用这个限制了,快来看看使用方法吧!!!!!!!!
?????? 内容 ??????
v 1. 活用me参考值
1.1认识me参考值
1.2程序传回me参考值
v 2. 认深入了解me参考值
1. 使用me参考值
1.1 认识me参考值
类别之程序成员(procedure member) 各含一个me参考变量﹐它永远参考到「目前对象」(current object)。目前对象就是正接受并处理讯息之对象。例如﹐
'ex01.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'------------------------------------------------------------------------------
public class fee
private amount as decimal
public sub new(byval amt as decimal)
me.amount = amt
end sub
public sub disp()
messagebox.show("amount is " + str( me.amount ))
end sub
end class
'--------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
.......
#end region
protected sub form1_click(byval sender as object,
byval e as system.eventargs)
dim a as new fee(100)
dim b as new fee(80)
a.disp()
b.disp()
end sub
end class
此程序输出如下﹕amount is 100
amount is 80
a 和 b是fee类别之对象。当计算机执行指令──
a.disp()
a 就是目前对象﹐disp()程序里的me正参考到对象a。
也可看成:
图1、 me参考值与目前对象
请注意﹕me参考到对象a﹐也就是me与a皆参考到同一个对象。
当计算机执行另一指令── b.disp()时,b 即为目前对象﹐而disp()程序之me参考正指向对象 b。
由于me正参考到对象b﹐所以me与b参考到同一个对象。写程序时﹐宜充分利用me参考。
1.2 程序传回me参考值
在应用上﹐程序常传回me参考值﹐可创造奇妙的效果﹐这种效果也是vb的重要特色。希望您能仔细了解me指针之使用场合﹐能让您写出完美的oop程序来﹗现在﹐请看个熟悉的程序──
'ex02.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'------------------------------------------------------------------------------
public class money
private balance as decimal
public sub new(byval amount as decimal)
balance = amount
end sub
public sub add(byval saving as decimal)
balance = balance + saving
end sub
public sub display()
messagebox.show("balance is " + str(balance))
end sub
end class
'--------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
.......
#end region
protected sub form1_click(byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.add(300)
orange.add(80)
orange.display()
end sub
end class
此程序输出如下﹕balance is 480
money 类别的 balance资料﹐记录存款余额。main()内之对象orange接受两讯息──add(300)及add(80) ﹐欲存入两项金额。
指令── orange.add(300)
orange.add(80)
表示﹕先存入 300元再存入80元﹐有先后次序。若上述图形改为──
则更具次序感。于是﹐上述指令相当于──
这种效果﹐不太陌生吧﹗回忆小学时,班长喊着:「起立、敬礼、坐下」,您不是连续接受到三个讯息吗?渐渐地﹐您已能设计出像日常生活这般亲切之对象了。不过﹐俗语说﹕「万丈高楼平地起」﹐还是必须先对me参考有充分了解才行﹗请看个程序──
'ex03.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'-----------------------------------------------------------------------------------
public class money
private balance as decimal
public sub new(byval amount as decimal)
balance = amount
end sub
public function add(byval saving as decimal) as money
balance = balance + saving
add = me
end function
public sub display()
messagebox.show("balance is " + str(balance))
end sub
end class
'----------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
.......
#end region
protected sub form1_click(byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.add(300).add(80)
orange.display()
end sub
end class
此程序输出如下﹕balance is 480
由于me永远参考到目前对象﹐此刻me正参考到对象orange。
图2、 程序传回目前对象之参考值
oragne对象就是me所指之对象﹐也可以说me与orange皆参考到同一个对象。指令──
add = me
传回目前对象之参考值──即orange对象之参考。add() 程序之定义──
于是add()把目前对象之参考值me传回form1_click()。此刻﹐orange.add(300)之值也是参考值,与orange参考到同一个对象。
于是,form1_click()程序之指令──
成为orange对象之别名了。
原来的指令── orange.add(300).add(80)
相当于── orange.add(80)
不过﹐此时orange对象之 balance变量值为400元﹐而非原来的100元了。此orange再接受讯息── add(80)﹐其 balance值增加为480 元。orange接到第 2个讯息── add(80)时﹐计算机再执行add() 程序﹐其再度传回orange的参考值﹐使得整个指令──
又成为orange之别名。因之﹐亦能把disp()讯息接于其后﹐如下﹕
'ex04.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'------------------------------------------------------------------------------------
public class money
private balance as decimal
public sub new(byval amount as decimal)
balance = amount
end sub
public function add(byval saving as decimal) as money
balance = balance + saving
add = me
end function
public sub display()
messagebox.show("balance is " + str(balance))
end sub
end class
'-------------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
.......
#end region
protected sub form1_click( byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.add(300).add(80).display()
end sub
end class
此程序输出如下﹕balance is 480
orange对象接到第 1个讯息──add(300)﹐计算机就执行add()程序,执行到结尾指令﹐传回me(即orange对象)参考值。此时form1_click()的orange.add(300)就是orange对象之参考值﹐亦即orange.add() 是orange对象之别名﹔则orange和 orange.add(300)重合在一起﹐代表着同一对象──原来的orange对象。
接下来﹐第 2个讯息──add(80)传给orange.add(300) ﹐相当于传给orange对象。再度执行到 add()里的的add = me指令时﹐又令orange.add(300).add(80) 成为 orange.add(300)之别名﹐即orange之别名﹔于是﹐三者代表同一对象──原来的orange对象。
接下来﹐第3个讯息──display传给orange.add(300).add(80) ﹐相当于传给orange对象。
于是输出orange对象内的balance值。
以程序传回me参考值之技巧将应用于许多方面。为了更了解这种方法﹐请看个特殊情形── 程序传回新对象之参考值。此对象不是目前对象,但内容是从目前对象拷贝而来。这不同于传回me参考值的情形﹐两种用法常令人搞混﹗现在﹐把程序改为──
'ex05.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'------------------------------------------------------------------------------------
public class money
private balance as decimal
public sub new(byval amount as decimal)
balance = amount
end sub
public function add(byval saving as decimal) as money
dim newobj as money
newobj = new money( balance + saving )
add = newobj
end function
public sub display()
messagebox.show("balance is " + str(balance))
end sub
end class
'-------------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
.......
#end region
protected sub form1_click( byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.add(300).add(80).display()
end sub
end class
此程序输出如下﹕balance is 480
当orange对象接到第 1个讯息──add(300)﹐计算机就执行add()程序﹐诞生一个money类别的新对象﹐把目前对象内容(即orange对象之值)拷贝一份给form1_click()。这份拷贝就是orange.add(300)之值。
orange.add(300) 即为拷贝回来的那份对象﹐并非原来的orange对象。当讯息──add(80)传给orange.add(300)所代表的对象时﹐计算机就执行add()函数﹐此时目前对象是orange.add(300) 而非原来的orange。执行时﹐又把目前对象──orange.add(300)内容拷贝一份给新诞生的对象,传回给form1_click()程序﹐这份拷贝就是orange.add(300).add(80) 之值。
由于每回执行add()就产生一份新对象(虽然内容相同﹐但占不同的内存空间)﹐其后的讯息皆传给add()所诞生之新对象﹐而非orange对象,所以这些讯息皆不影响原来orange对象之内容。
请注意﹕display()并未传回对象之参考值﹐则display()讯息之后不得再接其它讯息了。所以﹐如果form1_click()程序改写如下,那就错了──
protected sub form1_click( byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.add(300).display().add(80) 'error!
end sub
end class
因display()不传回对象之参考值﹐则指令──
其后之讯息──add(80) 是错的。如何改正呢﹖很简单﹐只需叫display()程序传回 me(目前对象之参考值)或新对象之参考值即可﹐如下﹕
'ex06.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'-------------------------------------------------------------------------------------
public class money
private balance as decimal
public sub new(byval amount as decimal)
balance = amount
end sub
public function add(byval saving as decimal) as money
dim newobj as money
newobj = new money( balance + saving )
add = newobj
end function
public function display() as money
messagebox.show("balance is " + str(balance))
display = me
end function
end class
'-----------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
........
#end region
protected sub form1_click(byval sender as object,
byval e as system.eventargs)
dim orange as new money(100)
orange.display().add(300).display().add(80).display()
end sub
end class
此程序输出﹕
balance is 100
balance is 400
balance is 480
此程序中﹐orange先接受display()讯息﹐印出存款额﹔再接受add(300)讯息﹐使存款额提高 300元﹐再接受display()讯息﹐依序下去。display()传回来目前对象orange之参考值,add()则传回新诞生对象之参考值。
2. 深入了解me参考
vb在编译时﹐会自动为程序成员产生me参考变量﹐并令me固定参考到目前对象(current object)。于此将细谈vb如何产生me参考变量﹐让您更能深刻了解me参考变量的特性和角色。首先﹐vb在编译程序成员时﹐会暗中偷加上1 个参考参数──me﹐成为该程序成员的第1 个参数。例如﹕
class person
private name as string
priavte age as integer
public sun new(byval na as string, byval a as integer)
name = na
age = a
end sub
public sub display()
messagebox.show( name + ", " + str( age ) )
end sub
end class
在编译此程序时﹐vb会将偷加上me参考变量如下﹕
class person
private name as string
priavte age as integer
public sun new( byval me as person, byval na as string,
byval a as integer)
me.name = na
me.age = a
end sub
public sub display(byval me as person)
messagebox.show( me.name + ", " + str( me.age ) )
end sub
end class
无论是在new()或display()程序里﹐me皆固定参考到目前对象﹐您不能改变me之值。接下来﹐请看如何令me参考到目前对象﹖假如有个form1_click()程序如下﹕
sub form1_click( .... )
dim x as new person("tom", 26)
x.display()
end sub
vb在编译时﹐会把指令──x.display()转换为﹕
person_display(x)
意谓着﹕呼叫person类别的display()程序来处理x 对象之内容。在呼叫这程序时﹐就把x参考值传递给display()程序里的me参数﹐如下﹕
于是﹐me就固定指向x对象了﹐而这x 对象就是我们欲处理之对象﹐亦
即就是目前对象了。请再看个例子吧﹗若person类别改为﹕
class person
private name as string
priavte age as integer
public sun new(byval na as string, byval a as integer)
name = na
age = a
end sub
public sub print()
me.display()
end sub
public sub display()
messagebox.show( name + ", " + str( age ) )
end sub
end class
则vb会为这3 个程序成员加上me参考值。其中print()程序转换如下﹕
public sub print(byval me as person)
person_display( me )
end sub
上述的me.display()转换为person_display( me )之后﹐就把这print()内的me值传给了display()内的me了﹐此时两个程序内的me皆参考到目前对象了。
以上所提的一般程序成员并不包括共享程序成员(shared member function)。还记得吗﹖共享程序成员的目的是﹕处理有关整个类别的事情﹐而不是用来处理对象之内容。在另一方面﹐me参考到目前对象﹐一般程序成员经由me来存取目前对象之内容。既然共享程序成员不需存取某特定对象之值﹐当然就不需要me参考变量了﹐因之vb并不会为共享程序成员偷加上me参考变量。简而言之﹐vb的规则是──
「vb编译时﹐并不会为共享程序成员加上me参考变量﹐所以
共享程序成员里没有me参考变量﹐也就无法存取对象之内容」
如前面所述﹐在呼叫一般程序成员时﹐必须把目前对象之参考值传递过去给该程序成员。但共享程序成员里并无me参考﹐所以无法呼叫一般程序成员。可得知vb的规则──
「共享程序成员不能呼叫一般程序成员﹐但可呼叫别的共享程序成员」
反之﹐一般程序成员却可呼叫共享程序成员。例如﹕
class person
private name as string
priavte age as integer
shared plast as person
public sun new(byval na as string, byval a as integer)
name = na
age = a
plast = me
end sub
shared sub displast()
plast.display()
'display() error !!
end sub
public sub print()
displast()
end sub
public sub display()
messagebox.show( name + ", " + str( age ) )
end sub
end class
display()是一般程序成员﹐共享程序成员displast()不能直接呼叫display()程序如下﹕
shared sub displast()
display() error !!
end sub
因为vb会将之转换为──
shared sub displast()
person_display( me ) error !!
end sub
但displast()是共享程序成员﹐并无me参考变量﹐所以错了。至于print()
呼叫displast()﹐vb将之转换为──
public sub print( byval me as person )
person_displast()
end sub
虽然print() 内有me参考﹐但displast()是静态程序成员并不需要me
﹐print() 并未把me传给displast()﹐这是对的