2013-02-12 78 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; 
     } 
    } 
}