【问题标题】:Operator Overloading causes a stack overflow运算符重载导致堆栈溢出
【发布时间】:2011-02-27 17:23:45
【问题描述】:

几天前我开始使用 C# 编程。

现在在玩操作符重载时会出现一个令人困惑的错误。

以下代码在运行时会产生 StackOverflowException

using System;

namespace OperatorOverloading
{
    public class Operators
    {
        // Properties
        public string text
        {
            get
            {
                return text;
            }

            set
            {
                if(value != null)
                    text = value;
                else
                    text = "";
            }
        }

        // Constructors
        public Operators() : this("")
        {
        }

        public Operators(string text)
        {
            // Use "set" property.
            this.text = text;
        }

        // Methods
        public override string ToString()
        {
            return text;
        }

        // Operator Overloading
        public static string operator +(Operators lhs, Operators rhs)
        {
            // Uses properties of the passed arguments.
            return lhs.text + rhs.text;
        }

        public static void Main(string[] args)
        {
            Operators o1 = new Operators();
            Operators o2 = new Operators("a");
            Operators o3 = new Operators("b");

            Console.WriteLine("o1: " + o1);
            Console.WriteLine("o2: " + o2);
            Console.WriteLine("o3: " + o3);

            Console.WriteLine();

            Console.WriteLine("o1 + o2: " + (o1 + o2));
            Console.WriteLine("o2 + o3: " + (o2 + o3));
        }
    }
}

在阅读了 Dirk Louis 和 Shinja Strasser 的“Microsoft Visual C# 2008”一书中关于运算符重载的章节后,我尝试编写一个自己的示例。

也许有人知道出了什么问题。

谢谢。

【问题讨论】:

  • 您的 Main 位于 Operators 类中,这是您故意要做的吗?
  • 只是好奇......为什么接受的答案从我的变成好奇的极客?一般规则是将提供有效解决方案的第一个答案标记为已接受。

标签: c# overloading stack-overflow operator-keyword


【解决方案1】:

首先,运算符重载不会破坏您的代码。你得到一个StackOverflowException,因为你的text 属性的getter 试图返回自己。

您应该为您的属性使用支持字段:

private string _text;

public string Text
{
    get { return _text; }
    set
    {
        if (value != null)
            _text = value;
        else
            _text = string.Empty;
    }
}

.NET 在幕后所做的就是将您的属性转换为访问器和变更器——这两个独立的方法。在您的原始示例中,您的代码将执行以下操作:

private string text;

public string get_text()
{
    return get_text(); // <-- StackOverflowException
}

public void set_text(string value)
{
    this.text = value;
}

而更正后的版本正确地使用了支持字段:

private string text;

public string get_text()
{
    return this.text; // Happy :)
}

public void set_text(string value)
{
    this.text = value;
}

【讨论】:

  • 我看到大量的运算符重载。但是,您的回答是正确的。
  • @Mike - 是的,我没有向下滚动足够远。哎呀!
【解决方案2】:

您的类中的 get 代码块有问题,这就是导致 StackOverFlow 异常的原因。

    public string text
    {
        get
        {
            return text;
        }
    }

在这里,当您说return text; 时,它会调用导致堆栈溢出的属性text 本身的get 块。将您的属性文本包裹在私有 _txt 字符串字段周围,它应该可以正常工作。

你可以把它做成这样的..

private string _txt;
public string text
{
    get
    {
        return _txt;
    }

    set
    {
        _txt = string.IsNullOrEmpty(value) ? string.Empty : value;
    }
}

【讨论】:

    【解决方案3】:

    问题是文本属性返回自身 你应该有一个受保护的或私有的变量来存储结果:

    // Properties
        private string _text
        public string text
        {
            get
            {
                return _text;
            }
    
            set
            {
                if(value != null)
                    _text = value;
                else
                    _text = "";
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2015-05-21
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2015-12-21
      相关资源
      最近更新 更多