2013-02-12 73 views
1

因此,在一些C#代碼,我也有類似的兩個屬性的東西:性質更新彼此

private string _foo; 
private string _bar; 

public Foo 
{ 
    get; 
    set { 
     _foo = value; 
     Bar = _foo.Substring(3, 5); 
    } 
} 

public Bar 
{ 
    get; 
    set { 
     _bar = value; 
     Foo = "XXX" + _bar; 
    } 
} 

問:是C#性能受到循環引用/更新,像這樣的例子似乎引起?

+0

你是否在控制檯應用程序和結帳嘗試這個? – Dhawalk 2013-02-12 21:57:28

+0

那麼,當你運行你的程序時,你會看到一個無限循環嗎? – 2013-02-12 21:57:30

+1

@PhilipHanson也許它仍在運行? :-) – LarsTech 2013-02-12 21:58:20

回答

1

您可以通過直接更新隱藏字段,這樣就避免了無限循環:

private string _foo; 
private string _bar; 

public string Foo 
{ 
    get { return _foo; } 
    set { 
     _foo = value; 
     _bar = _foo.Substring(3, 5); 
    } 
} 

public string Bar 
{ 
    get { return _bar; } 
    set { 
     _bar = value; 
     _foo = "XXX" + _bar; 
    } 
} 

這將繞過另一個屬性的setter,這消除了循環。

......這通常會導致以後的維護問題。就個人而言,我會嘗試尋找替代設計。

+0

我衷心地贊同替代設計;部分問題在於我的一個屬性是另一個屬性的碎片,然而由於我們系統的其他部分,更新碎片可能(並且應該出於完整性目的)用於更新超集。 **我的課程**:道具更新不是這份工作的正確工具。 – 2013-02-12 22:07:47

+1

如何通過單獨的方法更新片段,但允許通過只讀屬性訪問片段?不知道您的設置是否可行。是否需要通過屬性進行更新? – 2013-02-12 22:13:21

+0

這不是通過屬性更新的要求。 :)我會用這一點的代碼戰術。感謝您的寶貴意見! – 2013-02-12 22:15:04

2

是否C#屬性受循環引用/更新,就像這個例子似乎會導致?

是的。這裏有一個很好的無限循環。在C#

+0

接受了菲利普漢森的回答,儘管你提供了直接的答案。原因:他添加了一個可以避免該問題的實現,儘管所討論的設計並不理想。 – 2013-02-12 22:12:03

1

屬性是簡單的方法(getter和setter)。你從其他方法調用一個方法,反之亦然。結果是完全預期的。

這會令你感到驚訝?

public void set_Foo(string value) 
{ 
    set_Bar(value.Substring(3, 5)); 
} 

public void set_Bar(string value) 
{ 
    set_Foo("XXX" + value); 
} 

呼叫set_Foo("XXX12345")和..你會看到這個網站的名稱

+0

我知道獲取/設置實際上是引擎蓋下的方法......並不確定是否有一些終止因子*也隱藏在引擎蓋下面,以防止我看到堆棧溢出。現在,我知道答案是一個響亮的**沒有**。 – 2013-02-12 22:13:51

+0

@AndrewGray確切地說,編譯器只是簡單地生成名爲'get_'和'set_'以及方法體等於屬性體的方法。沒有更多 – 2013-02-12 22:16:24

1

爲了避免無限循環,這裏是菲利普·漢森的回答一種替代方案:只運行二傳手線當值實際上改變。對人好點;這是我的第一篇文章/回答

private string _foo; 
private string _bar; 

public Foo 
{ 
    get; 
    set { 
     if (_foo != value) 
     { 
     _foo = value; 
     Bar = _foo.Substring(3, 5); 
     } 
    } 
} 

public Bar 
{ 
    get; 
    set { 
     if (_bar != value) 
     { 
     _bar = value; 
     Foo = "XXX" + _bar; 
     } 
    } 
}