Stack overflow exception in C# setter
This works:
using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;
namespace ConsoleApp开发者_运维百科lication2
{
class test
{
public ConstraintSet a { get; set; }
public test()
{
a = new ConstraintSet();
}
static void Main(string[] args)
{
test abc = new test();
Console.WriteLine("done");
}
}
}
This does not:
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");
}
}
}
I get a stack overflow exception on a's setter in the second class and I do not know why. I cannot use the first form because it is not supported by the Unity game engine.
When you write a = value
, you are calling the property setter again.
In order to use non-automatic properties, you need to create a separate private backing field, like this:
ConstraintSet a;
public ConstraintSet A { get { return a; } set { a = value; } }
You haven't declared a backing variable - you've just got a property whose getters and setters call themselves. It's not clear to me why the first form isn't supported by Unity - which means it's possible that the equivalent won't be supported either, but it's basically this:
private ConstraintSet aValue;
public ConstraintSet a { get { return aValue; } set { aValue = value; } }
I'd normally have a more conventional name, of course - which means you can get away without the "value` bit:
private ConstraintSet constraints;
public ConstraintSet Constraints
{
get { return constraints; }
set { constraints = value; }
}
To give a bit more detail as to why your current second form is throwing a StackOverflowException
, you should always remember that properties are basically methods in disguise. Your broken code looks like this:
public ConstraintSet get_a()
{
return get_a();
}
public void set_a(ConstraintSet value)
{
set_a(value);
}
Hopefully it's obvious why that version is blowing the stack. The amended version just sets a variable instead of calling the property again, so it looks like this when expanded:
private ConstraintSet aValue;
public ConstraintSet get_a()
{
return aValue;
}
public void set_a(ConstraintSet value)
{
aValue = value;
}
You cannot use the same variable name inside the getter and setter. This will cause it to call itself and will eventually lead to a stack overflow. Too much recursion.
You'll need a backing variable:
private ConstraintSet _a;
public ConstraintSet a { get { return _a; } set { _a = value; } }
You need a private backing variable in your public property:
private ConstraintSet _a;
public ConstraintSet a { get { return _a; } set { _a = value; } }
精彩评论