我几天前开始用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”一书中有关operater重载的章节之后,我尝试编写了一个自己的例子。
也许有人知道出了什么问题。
感谢。
答案 0 :(得分:10)
嗯,首先,运算符重载不会破坏您的代码。您得到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;
}
答案 1 :(得分: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;
}
}
答案 2 :(得分:1)
问题是text属性返回自身 您应该有一个受保护或私有的变量来存储结果:
// Properties
private string _text
public string text
{
get
{
return _text;
}
set
{
if(value != null)
_text = value;
else
_text = "";
}
}