Перегрузка оператора вызывает переполнение стека - PullRequest
5 голосов
/ 27 февраля 2011

Я начал программировать на 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));
        }
    }
}

Я попытался написать собственный пример после прочтения главы о перегрузке оператора из книги «Microsoft Visual C # 2008» от Дирка Луи и Синдзя Штрассера.

Может быть, кто-тоПонятия не имею, что происходит.

Спасибо.

Ответы [ 3 ]

10 голосов
/ 27 февраля 2011

Ну, например, перегрузка оператора не нарушает ваш код.Вы получаете StackOverflowException, потому что получатель вашего text свойства пытается вернуть себя.

Вы должны использовать вспомогательное поле для вашего свойства:

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;
}
2 голосов
/ 27 февраля 2011

Проблема с блоком кода get в вашем классе, и именно это вызывает исключение StackOverFlow.

    public string text
    {
        get
        {
            return text;
        }
    }

Здесь, когда вы говорите return text;, он идет и вызывает блок get самого свойства text, которое вызывает переполнение стека. оберните текст вашего свойства вокруг частного строкового поля _txt, и оно должно работать правильно.

Вы можете сделать что-то вроде этого ..

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

    set
    {
        _txt = string.IsNullOrEmpty(value) ? string.Empty : value;
    }
}
1 голос
/ 27 февраля 2011

Проблема в том, что текстовый proprty возвращается сам. У вас должен быть защищенный или закрытый переменный для хранения результата:

// Properties
    private string _text
    public string text
    {
        get
        {
            return _text;
        }

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