2010-07-18 150 views
7

这是简单的解释: 这个作品堆栈溢出异常

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get; set; } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

这并不

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get { return a; } set { a = value; } } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

我得到一个堆栈溢出异常上的二传手在第二类和我做不知道为什么。我不能使用第一种形式,因为它不受统一引擎的支持

+0

'我不能使用第一种形式,因为它不是由统一engine'支持...第一种形式是一个编译器级的简写。它应该适用于统一引擎。 – SLaks 2010-07-18 15:44:48

+1

[类属性上的StackOverFlow]的可能重复(http://stackoverflow.com/questions/680765/stackoverflow-on-class-property)以及其他许多。 – 2010-07-18 15:45:55

+0

nope,unity c#编译器不支持这种语法 – Patrik 2010-07-18 15:56:41

回答

24

当您编写a = value时,您再次调用属性设置器。

为了使用非自动属性,你需要创建一个独立的私人支持字段,就像这样:

ConstraintSet a; 
public ConstraintSet A { get { return a; } set { a = value; } } 
+1

不知道为什么这个答案是downvoted,因为它是更多的信息,科里拉尔森的... – 2010-07-18 15:48:49

+0

@Jon:我很惊讶我得到任何投票时,我只是张贴你身后的秒数:P。我今天早上太昏昏沉沉地解释**为什么**,所以毫无疑问,SLak和你的答案都更好。 – 2010-07-18 16:44:44

+0

@Cory:我没有特别反对你的回答,因为它确实解决了问题 - 但没有解决问题。可能有人只是不喜欢高代表的人。 – 2010-07-18 16:46:16

15

您还没有声明的后盾变量 - 你拿到它的属性获得者和制定者称自己。这不是很清楚,我为什么第一种形式不统一的支持 - 这意味着它有可能是相当于将不进行支持,但它基本上是这样的:

private ConstraintSet aValue; 
public ConstraintSet a { get { return aValue; } set { aValue = value; } } 

我通常有更传统的名字,当然 - 这意味着你可以逃脱没有“value`位:

private ConstraintSet constraints; 
public ConstraintSet Constraints 
{ 
    get { return constraints; } 
    set { constraints = value; } 
} 

为了给多一点细节,为什么你目前的第二种形式抛出StackOverflowException,你应该永远记住,属性基本上是伪装的方法。破碎的代码如下所示:

public ConstraintSet get_a() 
{ 
    return get_a(); 
} 

public void set_a(ConstraintSet value) 
{ 
    set_a(value); 
} 

希望这很明显,为什么这个版本吹的堆栈。修改后的版本只是设置一个变量,而不是再次调用的属性,所以扩展时,它看起来是这样的:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } } 
+0

@Downvoter:小心给个理由? – 2010-07-18 15:47:20

+0

只是统一的C#编译器不支持什么可视化的C#。这是因为它必须保持兼容性与单声道 – Patrik 2010-07-18 16:00:23

+0

@Patrik:Mono也支持C#3 ... C#3已经出现了近3年;这不完全是一个新功能。 – 2010-07-18 16:03:15

3

你在你的公共财产需要一个私人的支持变量getter和setter中的相同变量名称。
这将导致它自己调用,并最终将stackoverflow。递归太多。
你需要一个后盾变量:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } } 
3

不能使用:

private ConstraintSet aValue; 

public ConstraintSet get_a() 
{ 
    return aValue; 
} 

public void set_a(ConstraintSet value) 
{ 
    aValue = value; 
}