2011-10-24 168 views
1

假設我有類似如下的對象初始化:如何引用在初始化程序中用c#初始化的對象?

var coolObject = new CoolObject() 
{ 
    GetObjectState =() => coolObject.InternalState; 
} 

哪裏GetObjectState是返回某種對象的狀態上CoolObject的功能。在這種情況下,我希望該函數簡單地返回coolObject的內部狀態對象。代碼對象顯然不會編譯,因爲在聲明它之前不能引用局部變量。

有沒有辦法解決這個問題?是否有類似於初始化程序的「this」關鍵字?

+0

你必須使用構造函數嗎?有什麼原因讓你不能在CoolObject上擁有一個靜態屬性並將其用於你的任務? – wsanville

+0

@wsanville可能因爲不同的實例需要返回不同的對象狀態。 –

+1

這是不是構造函數的一部分的原因嗎?這就是我們有建設者採取論據和做事的原因之一。 –

回答

3
CoolObject coolObject = null; 
coolObject = new CoolObject() 
{ 
    GetObjectState =() => coolObject.InternalState; 
} 

雖然如果coolObject的值在調用之前發生更改,此代碼是不安全的。

+0

這會編譯,當然,但不會我的匿名方法指向一個空引用的對象?它會指向coolObject的第一個聲明,它指向堆上的空值。然後當第二行運行時,它會在堆上創建一個新對象,但是我的方法仍然會指向第一個,不是? –

+0

@JonathanBeerhalter這很好; lambda關閉了*變量*,而不是變量的值。第二行運行後,懸掛的變量將引用非空的'CoolObject'。不過,這是一個危險且不必要的計劃。只是重構,所以你不必這樣做。 – dlev

+0

匿名方法將指向coolObject,一旦它被執行,它會找出coolObject的值。我不記得實際發生了什麼,但我相信類是生成的,其中一個引用了coolObject,而不是坐在堆上的,而是當前坐在堆棧上的coolObject的值。 –

2

你就不能刪除{},即什麼是錯的:

var coolObject = new CoolObject(); 
coolObject.GetObjectState =() => coolObject.InternalState; 
1

在闡述我的意見:有沒有理由使用這種方法。你幾乎可以肯定更好只是定義GetObjectState作爲一個實際的方法,而不是Func<TypeOfInternalState>

public TypeOfInternalState GetObjectState() { return this.InternalState } 

現在有沒有需要編譯器吊起一個局部變量,也沒有怪異的建築語法,其中你提到的一個引用當前正在構造的對象的變量。

+0

沒錯,但是你不能改變GetObjectState()在運行時如何執行。我不能調用GetObjectState = {這裏有一些代碼} –

+0

我想,但這仍然是一個非常脆弱的方法。在派生類中創建「虛擬」方法然後重寫,幾乎完全相同,除了以安全和明顯的方式。我明白當你確實希望類的消費者指定行爲時(儘管如此,它通常作爲構造函數的參數被設置一次)的思想,但是考慮到你的方法旨在檢索對象的狀態(a非常私人的操作,只能由對象本身來完成)我認爲應該避免你的方法。 – dlev

1

如何:

public class CoolObject 
{ 
    public CoolObject() 
    { 
     GetObjectState =() => this.InternalState; 
    } 

    public Func<InternalState> GetObjectState; 
} 

您可以覆蓋你的心臟的內容和默認狀態適用於大多數情況下。