asp.net c#类属性stackoverflow异常

时间:2011-09-20 19:18:23

标签: c# asp.net

我有一个非常简单的C#类:

namespace mybox
{
    public class userAccount : IMyInterface
    {
        public userAccount()
        {
        }
        private int _userId;
        private string _userName;

        public int userId
        {
            get { return _userId; }
            set { userId = value; }
        }
        public string userName
        {
            get { return _userName; }
            set { userName = value; }
        }

        public string list(int myUserId)
        {
            ...
           myOutPut = string.Format("{0} {1} {2}", u.userId, u.userName);
           return myOutPut.ToString();
        }

    public void add()
    {
           pillboxDataContext db = new pillboxDataContext();
           userAccount newUser = new userAccount();
           newUser.userName = "test123";

           db.SubmitChanges();
       }
    }
}

在Page_Load事件的default.aspx.cs中,我试图调用list方法:

protected void Page_Load(object sender, EventArgs e)
{
    pillbox.userAccount myUA = new pillbox.userAccount();
    myUA.add();

// Console.WriteLine(myUA.list(1));

}

当我调用add方法时,我可以看到它正在尝试将值test123分配给属性,但是我得到以下消息:

App_Code.1zm0trtk.dll中发生未处理的“System.StackOverflowException”类型异常

我正在做错的任何想法?

4 个答案:

答案 0 :(得分:5)

问题在于您定义属性的方式。

您正在尝试引用要在setter中为其指定值的属性 导致infinte递归(具体来说,这一行触发它newUser.userName = "test123";)。

将它们更改为:

public int userId         
{             
    get { return _userId; }             
    set { _userId = value; }         
}         

public string userName         
{             
        get { return _userName; }             
        set { _userName = value; }         
} 

答案 1 :(得分:3)

这是因为userName调用自身。你可能想要分配字段:

这一行错了:

set { userName = value; }

你打算写:

set { _userName = value; }

答案 2 :(得分:2)

您需要设置私人支持字段,而不是属性。否则你只是在整个时间调用自己设置时进入无限递归。

    private int _userId;
    private string _userName;

    public int userId
    {
        get { return _userId; }
        set { _userId = value; }
    }
    public string userName
    {
        get { return _userName; }
        set { _userName = value; }
    }

在您的情况下,您可以使用自动实现的属性(我更改了外壳以符合指南):

public int UserId { get; set; }
public string UserName { get; set; }

答案 3 :(得分:2)

如果你重新写一下你的二传手,很容易看出发生了什么。属性上的getset实际上已编译为方法(PropType get_PropName()void set_PropName(PropType value)),并且对属性的任何引用都将编译为对相应方法的调用。所以这段代码:

int i = myObj.MyIntProp;
myObj.MyIntProp = 6;

编译到

int i = myObj.get_MyIntProp();
myObj.set_MyIntProp(6);

所以你的二传手

set
{
    username = value;
}

实际编译为

public void set_username(string value)
{
    set_username(value);
}

现在堆栈溢出的原因很明显。