none
如何手動銷毀物件實體 RRS feed

  • 問題

  • 今天遇到的需求如下

    類別B只能限定類別A呼叫

    一開始我是使用以下寫法

    Public Class B
        Private Sub New()
    
        End Sub
    
        Public Shared Function getObject(ByVal obj As Object) As Object
            If obj.GetType.Name = "A" Then
                Return New B
            End If
            Return Nothing
        End Function
    End Class

    但是老闆指定說,必須透過NEW這個關鍵字,不能帶參數

    這樣就等於需要在建構子中下手

    如果是這樣,那我應該要怎麼樣去驗證是否為類別A所呼叫

    如果不是,又該如何去銷毀這個已經實體化的類別呢??

    2013年3月6日 下午 08:12

解答

所有回覆

  • 類別B只能限定類別A呼叫 <--- 類別 B 和 A 的關係是什麼 ?

    執行個體的生命周期是: 在一般狀況下, 當沒有任何一個變數參考到該執行個體時, CLR 會將其自動排入回收機制中.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年3月6日 下午 11:29
    版主
  • 您好,

    可試一下 StackTrace , 如下,

    Public Class A
        Public Sub methodA()
            Dim myBClass As New B
        End Sub
    
    
    End Class
    
    Public Class B
        Public Sub New()
            Dim trace As StackTrace = New StackTrace
            Dim frame As StackFrame = trace.GetFrame(1)
            Dim callerMethod = frame.GetMethod()
            '你可以判斷callerTypeName是不是A
            Dim callerTypeName = callerMethod.DeclaringType.Name
        End Sub
    End Class


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2013年3月6日 下午 11:57
  • 這種方法呢?


    理直氣和,切記。

    Blog: http://blog.kkbruce.net

    Book:《ASP.NET MVC 4 網站開發美學》,2/7號正式上市

    2013年3月7日 上午 01:38
  • Hi,

    如果某類別只該被特定類別使用

    那麼巢狀類別的確比較適用

    如果是用程式判斷呼叫者

    那麼這樣的函式庫給別人使用時

    會有誤用的可能

    不看你的Code沒人能理解有這樣的關係


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年3月7日 上午 02:30
  • 類別B只能限定類別A呼叫 <--- 類別 B 和 A 的關係是什麼 ?

    執行個體的生命周期是: 在一般狀況下, 當沒有任何一個變數參考到該執行個體時, CLR 會將其自動排入回收機制中.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    這兩個類別本身並沒有關係

    這樣的需求是為了防呆

    避免工程師一個不小心在不該使用的地方下了NEW

    導致執行時記憶體倍增

    就像您說的回收機制是必須在沒有任何外來的變數指到該類別時才有可能回收

    得要想辦法強制讓不允許的類別放掉類別B的實體

    因為跑入建構函式等於初始化完成了...


    2013年3月7日 上午 05:31
  • 您好,

    可試一下 StackTrace , 如下,

    Public Class A
        Public Sub methodA()
            Dim myBClass As New B
        End Sub
    
    
    End Class
    
    Public Class B
        Public Sub New()
            Dim trace As StackTrace = New StackTrace
            Dim frame As StackFrame = trace.GetFrame(1)
            Dim callerMethod = frame.GetMethod()
            '你可以判斷callerTypeName是不是A
            Dim callerTypeName = callerMethod.DeclaringType.Name
        End Sub
    End Class


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    感謝您提供了這一個方法,這樣就可以解決一半的問題了
    2013年3月7日 上午 05:39
  • 這種方法呢?


    理直氣和,切記。

    Blog: http://blog.kkbruce.net

    Book:《ASP.NET MVC 4 網站開發美學》,2/7號正式上市

    一開始我也是用內部類別配合靜態方法來決定要不要丟出內部類別的實體

    不過被打槍了...才有第二個也就是我在主樓寫的方法

    2013年3月7日 上午 05:41
  • Hi,

    如果某類別只該被特定類別使用

    那麼巢狀類別的確比較適用

    如果是用程式判斷呼叫者

    那麼這樣的函式庫給別人使用時

    會有誤用的可能

    不看你的Code沒人能理解有這樣的關係


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    如果真的找不到老闆指定的解決方法,那就只能退而求其次使用其他方式

    因為跑進建構函式就等於實體化完成了

    要想辦法銷毀這個物件實在是有些困難....

    況且這又要是類別內部本身去銷毀

    2013年3月7日 上午 05:49

  • 一開始我也是用內部類別配合靜態方法來決定要不要丟出內部類別的實體

    不過被打槍了...才有第二個也就是我在主樓寫的方法

    Hi,

    打槍的理由是什麼?我不覺得你後來的寫法比較好

    還有既然這個類別只有特定類別認得的話為甚麼要丟出內部的實體?

    可以把本來的code跟打槍的原因都列出來嗎?


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年3月7日 上午 06:04
  • 外部抽象, 內部私有, 這種方法可行嗎?

    Public MustInherit Class C
    	Public Property MyString As String
    End Class
    
    Public Class A
    	Private Class B
    		Inherits C
    
    	End Class
    
    
    	Public Property d As C
    	Sub New()
    		d = New B()
    		d.MyString = "ABC"
    	End Sub
    End Class


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年3月7日 上午 06:09
    版主
  • 換個問法~你覺得你的需求跟singleton有關嗎

    因為感覺你這些動作都是為了減少記憶體消耗

    但開出來又是因為要讓其它物件共用...


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年3月7日 上午 06:20

  • 一開始我也是用內部類別配合靜態方法來決定要不要丟出內部類別的實體

    不過被打槍了...才有第二個也就是我在主樓寫的方法

    Hi,

    打槍的理由是什麼?我不覺得你後來的寫法比較好

    還有既然這個類別只有特定類別認得的話為甚麼要丟出內部的實體?

    可以把本來的code跟打槍的原因都列出來嗎?


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    Public Class C
    
        Public Sub New()
    
        End Sub
    
        Private Class B
            Public Sub Test()
                MsgBox("OK")
            End Sub
        End Class
    
        Public Shared Function getObject(ByVal obj As Object) As Object
            If obj.GetType.Name = "A" Then
                Return New B
            End If
            Return Nothing
        End Function
    End Class

    這是我的第一個方法

    要使用時就這樣呼叫 

    Dim Sub_B As Object = C.getObject(Me)
            Sub_B.Test()

    被打槍是因為不要使用內部類別

    第二次就是我發問的那個方法,被打槍的原因是要透過New這個關鍵字

    經過溝通後,是因為這種公司底層要大改

    時間成本太重,所以才會說能不能透過先New,然後在建構子中想辦法驗證

    如果驗證不通過,就銷毀物件


    2013年3月7日 上午 06:59
  • 換個問法~你覺得你的需求跟singleton有關嗎

    因為感覺你這些動作都是為了減少記憶體消耗

    但開出來又是因為要讓其它物件共用...


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    的確,這跟單例是有關係的

    因為架構是一路繼承上來

    所以一旦參考加入後,之前所繼承的東西都可以用

    但是可能會有人不小心又實體化了一次

    這樣記憶體會是雙倍成長


    2013年3月7日 上午 07:18
  • Hi,

    我問一下~你是希望程式裡面只有一個物件實體B嗎?

    如果是的話~你該看一下singleton

    若是建構成本龐大的物件,也可以考慮使用weakreference

    另外你說到"如果驗證不通過,就銷毀物件"

    這種方法建議就不用試了

    雖然有.NET有GC

    但臨時性的物件都是GC的負擔

    Effective C#就有提到要盡量減少記憶體垃圾(條款十六)

    而且其實你的getObject都回傳object了

    又能接受用晚期繫結的方式下去撰寫

    我不覺得有什麼論點要禁用內部類別


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年3月7日 上午 07:18
  • 外部抽象, 內部私有, 這種方法可行嗎?

    Public MustInherit Class C
    	Public Property MyString As String
    End Class
    
    Public Class A
    	Private Class B
    		Inherits C
    
    	End Class
    
    
    	Public Property d As C
    	Sub New()
    		d = New B()
    		d.MyString = "ABC"
    	End Sub
    End Class


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    這個方式我會跟我老闆談談看

    很感謝您的提供

    2013年3月7日 上午 07:21
  • Hi,

    我問一下~你是希望程式裡面只有一個物件實體B嗎?

    如果是的話~你該看一下singleton

    若是建構成本龐大的物件,也可以考慮使用weakreference

    另外你說到"如果驗證不通過,就銷毀物件"

    這種方法建議就不用試了

    雖然有.NET有GC

    但臨時性的物件都是GC的負擔

    Effective C#就有提到要盡量減少記憶體垃圾(條款十六)

    而且其實你的getObject都回傳object了

    又能接受用晚期繫結的方式下去撰寫

    我不覺得有什麼論點要禁用內部類別


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    就..老闆個人的撰寫風格吧!!

    還是非常感謝您和每一個人撥空提供想法和建議

    2013年3月7日 上午 07:23
  • 討論了那麼久, 可不可以問問你老闆, 究竟原因是什麼, 我們大家都很好奇.

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年3月7日 上午 07:27
    版主
  • 討論了那麼久, 可不可以問問你老闆, 究竟原因是什麼, 我們大家都很好奇.

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    剛剛詢問了一下,因為是五六十個方案繼承

    每個方案中又有三到四個專案

    每個專案中又有一堆class

    每一隻class中如果再多一隻function或是更改結構,對於時間人力成本來講消耗有些大..

    這是老闆的說法


    2013年3月7日 上午 07:37
  • Hi,

    所以getObject是本來就在原程式裡面的方法嗎?

    那這樣修改成只有A物件呼叫會有物件實體傳出

    其它的專案都不用變動就可以判斷回傳Null後改由從A去取嗎?

    如果不會改由從A去取

    那C物件要用的B物件要從哪邊去取得?

    如果你只是為了暫時解決問題

    也許將本來的b物件變成一個wrapper物件會比較方便

    雖然可能有多個b物件

    但那只是一個很薄的殼


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年3月8日 上午 12:07
  • Hi,

    所以getObject是本來就在原程式裡面的方法嗎?

    那這樣修改成只有A物件呼叫會有物件實體傳出

    其它的專案都不用變動就可以判斷回傳Null後改由從A去取嗎?

    如果不會改由從A去取

    那C物件要用的B物件要從哪邊去取得?

    如果你只是為了暫時解決問題

    也許將本來的b物件變成一個wrapper物件會比較方便

    雖然可能有多個b物件

    但那只是一個很薄的殼


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    getObject 和 外層類別 是我為了要解決這個方式加上去的

    把原本的類別變成內部類別

    C物件就正常狀況下,加入的參考就要包含物件A

    2013年3月8日 上午 07:12