Me關鍵字在.NET中的使用(轉)

來源:互聯網
上載者:User
關鍵字 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()﹐這是對的

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。