C# setter 中的堆栈溢出异常

发布于 2024-09-10 16:42:53 字数 1106 浏览 8 评论 0原文

这有效:

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

我在第二类中的 a 的 setter 上遇到堆栈溢出异常,我不知道为什么。我无法使用第一种形式,因为 Unity 游戏引擎 不支持它。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

以歌曲疗慰 2024-09-17 16:42:53

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

为了使用非自动属性,您需要创建一个单独的私有支持字段,如下所示:

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

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; } }
愿得七秒忆 2024-09-17 16:42:53

您还没有声明支持变量 - 您只是获得了一个属性,其 getter 和 setter 调用自身。我不清楚为什么 Unity 不支持第一种形式 - 这意味着等效形式也可能不受支持,但基本上是这样的:

private ConstraintSet aValue;
public ConstraintSet a { get { return aValue; } set { aValue = 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 aValue;

public ConstraintSet get_a()
{
    return aValue;
}

public void set_a(ConstraintSet value)
{
    aValue = 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;
}
祁梦 2024-09-17 16:42:53

不能在 getter 和 setter 中使用相同的变量名。这将导致它调用自身并最终导致堆栈溢出。太多的递归。

您需要一个支持变量:

private ConstraintSet _a;
public ConstraintSet a { get { return _a; } set { _a = 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; } }
七度光 2024-09-17 16:42:53

您的公共财产中需要一个私有支持变量:

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; } }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文