在C#中使用属性访问器时引发无限循环错误

本文关键字:无限循环 错误 访问 属性 | 更新日期: 2023-09-27 18:20:52

我有第二个窗口,当搜索某个员工姓名时会打开,这个窗口会提示您在两个同名员工之间进行选择。然后,窗口需要向父窗口返回一个值,以便用xml文件中的相关数据填充数据模板。

我已经尝试创建一个字符串,该字符串将根据单击的按钮更新一个值,然后可以将该字符串返回到第一个窗口上的调用方法,并在Linq-to-Xml查询中填充绑定数据。

但当它运行时,会导致stackoverflow异常,并且它可能是一个无限循环。我对c#还不够确定,不知道该更改什么。

public partial class Choice : Window
{
    private string StaffChoice;
    public Choice()
    {                      
        InitializeComponent();
    }
    public string staffChoice
    {
        get { return this.StaffChoice; }
        set { staffChoice = StaffChoice; }
    }
    private void btnMRG_Click(object sender, RoutedEventArgs e)
    {
        StaffChoice = "MRG";
        this.Close();
    }
    private void btnRPG_Click(object sender, RoutedEventArgs e)
    {
        StaffChoice = "RPG";
        this.Close();
    }
}

任何帮助或建议都将是伟大的!

提前感谢!

在C#中使用属性访问器时引发无限循环错误

首先,您的命名约定是错误的-字段应被称为staffChoice属性应该被称为StaffChoice。有关详细信息,请阅读.NET命名约定。然而,现在仔细查看您的房产:

public string staffChoice
{
    get { return this.StaffChoice; }
    set { staffChoice = StaffChoice; }
}

你认为二传手做什么?它有两个问题:

  • 它会忽略您试图将其设置为的值
  • 它递归地调用自己

您可以通过保留手动声明的字段、修复命名约定并更改属性将变量设置为value来修复此问题,如下所示:

private string staffChoice;
public string StaffChoice
{
    get { return staffChoice; }
    set { staffChoice = value; }
}

然而,使用一个自动实现的属性会更简单:

public string StaffChoice { get; set; }

这将自动为您创建backing字段和getter/setter。

最简单的方法是声明这样的属性。。。

public string StaffChoice { get; set; }

您的问题是,您基本上是从同一个setter中调用属性setter,因此您有一个递归循环。你可以这样修改你的代码,使其工作。。。

private string StaffChoice;
public string staffChoice
{
    get { return this.StaffChoice; }
    set { StaffChoice = value; }
}

您的setter不正确,您正在为自己赋值(导致无限循环),而没有使用value

你应该把你的代码改成这样,你的命名约定向后看了,所以我纠正了它,希望你不介意:

private string staffChoice;
public Choice()
{                      
    InitializeComponent();
}
public string StaffChoice
{
    get { return staffChoice; }
    set { staffChoice = value; }
}
private void btnMRG_Click(object sender, RoutedEventArgs e)
{
    staffChoice = "MRG";
    this.Close();
}
private void btnRPG_Click(object sender, RoutedEventArgs e)
{
    staffChoice = "RPG";
    this.Close();
}

您的属性应该是:

public string staffChoice
{
    get { return this.StaffChoice; }
    set { this.StaffChoice = value; }
}

在您的代码中,您将在setter中再次调用setter,从而实现无限递归。

然而,由于您在setter中没有做任何特殊的操作(例如通知UI属性已经更改),您可以简单地使用:

public string staffChoice { get; set; }

这个"汽车房"稍微干净一点。

(顺便说一句:通常的做法是让back变量以小写字母开头,让public属性以大写字母开头。但是,如果你在应用程序中保持一致,那就无关紧要了。)