20

This works:

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");
        }
    }
}

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.

3
  • I cannot use the first form because it is not supported by unity engine ... The first form is a compiler-level shorthand. It should work fine with unity engine. – SLaks Jul 18 '10 at 15:44
  • 1
    possible duplicate of StackOverFlow on class property and lots of others. – Henk Holterman Jul 18 '10 at 15:45
  • nope, unity c# compiler does not support this syntax – Patrik Jul 18 '10 at 15:56
45

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; } }
0
20

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;
}
8
  • simply unity c# compiler does not support what visual c# does. this is because it has to mantain compatibility with mono – Patrik Jul 18 '10 at 16:00
  • @Patrik: Mono supports C# 3 as well... C# 3 has been out for nearly 3 years now; this isn't exactly a new feature. – Jon Skeet Jul 18 '10 at 16:03
  • i guess this is because of the mac compatibility. i do not know the exact reason but unity compiler says get and set must have a body – Patrik Jul 18 '10 at 16:23
  • 1
    @Patrik: Mac compatibility should have nothing to do with it. They could easily support it if they bothered - it doesn't require any new framework or runtime features. Basically it sounds like the Unity compiler is just somewhat out of date :( – Jon Skeet Jul 18 '10 at 16:25
  • 1
    @Dan: What makes you think there are two variables? There aren't - there's one field, and one property that provides access to it... just like in Java where you'd have a field and one or two methods to access it. And with automatically-implemented properties, even the field declaration is hidden. Where do you see two variables? – Jon Skeet Nov 9 '18 at 9:45
5

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; } }
3

You need a private backing variable in your public property:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.