C# 错误栈溢出异常(StackOverflowException)

private string _invoice;    
public string Invoice
    {
        get
        {
            if (string.IsNullOrEmpty(_invoice)==false && _s != "NULL") 
                    { return Invoice; } 
            else { return null; }
        }
        set
        {
            if (value.Length > 0) 
                _invoice =  value; 
            else
                _invoice = "NULL"; //项目需求,用于写入SQL数据库
        }
    }

上方第7行应为:

            { return _invoice; } 

get 方法不能返回变量自身的值,否则将陷入无限读取值的循环从而导致上述异常.


详细解释

原文链接:http://blog.sina.com.cn/s/blog_82526aa60100txtx.html

  在程序中经常碰到get、set,不甚明白,在网上查询时也说的迷迷糊糊,所以整理下,以学的明白透彻点。
  有两个类person:

public class person
{
    public string name;
}

public class person
{
    public string Name{set;get;}
}

  第一个类型的name属性未封装,其name属性直接通过public关键字暴露给系统中的其他类了,而第二个类型的name属性通过get和set关键字进行了封装,get和set分别对应的是可读和可写,相当于如下代码:

private string name;
public string Name
{
    get { return name; }
   set { name = value; }
}

  简单说下区别:当实例化第一个“person”这个类时,系统在分配内存空间时对name属性直接分配内存,之后对name属性的操作也是直接操作内存中name属性所在的这个块;而当实例化第二个“人”类型时,系统会先分配一个叫name的private私有的内存空间,之后的读与写的操作都是通过Name这个public的类似于指针的东西来关联name进行,以此达到封装的目的,并且通过get和set关键字也可以控制可读还是可写。建议用后者,封装的好处可以参考相关文档,不再累述。
  至于get和set的作用,除了控制读写之外还有其他的作用,举个简单的例子,比如说当我给Name赋值的时候想要先进行一些逻辑判断,就可以这样:

private string name;
public string Name
{
    get { return name; }
    set
    {
     name = String.IsNullOrEmpty(value) ? "空" : value;
    }
}

  再举例说明下:假设有一个银行类,既能存钱也能取钱

private Money;
private class bank()
{
    get{ return Money; }
    set{ Money=value; }
}

  Money 就像银行里的自动取款机,你看不见里面的Money,但你能用set(存钱),用get(取钱)。Money是一个私有字段,是封装在类中的,类以外的程序不能直接访问的。C#中get、set用法中,类的set和get成员是外部程序访问类内部属性的唯一方法,就像你去银行取钱,你不能直接从银行的保险柜里拿钱,而是银行营业人员把钱取出来给你的。
  属性在调用者看来就像一个普通的变量,但作为类的设计者,你可以利用属性来隐藏你类中的一些字段,使外界只能通过属性来访问你的字段,你可以通过属性来限制外界对你的字段的存取,就利用get、set。如果想让用户随意存取你的字段,那么就实现get、set;如果只想让用户读取字段,就只实现get;若只想让用户写字段就只实现set。同时还可以在set和get中对用户传递的值进行一些验证工作,以确保你的字段将含有正确的值。

private int a;
public int index
{
    get
    { return a; }
    set
    {
     If (value>0)
       a=value;
     else
       a=0;
    }
}

可看出,get、set用法有如下特点:

一则是隐藏组件或类内部的真是成员;
二是用来建立约束的,比如,实现“有我没你”这种约束;
三是用来响应属性变化事件,当属性变化是做某事,只要写在set方法里就行;

  当你想读出或写入属性的值时,存取标志限定了被实现的语句。用于读出属性的值的存取标志记为关键字get,而要修改属性的值的读写符标志记为set。

给TA打赏
共{{data.count}}人
人已打赏
odoo

如何在Ubuntu 22.04 (Jammy) 中安装odoo 16

2024-3-27 14:15:17

C#

ListView 绑定 List<> 使双边修改同步

2020-4-6 0:14:30

各类网站开发

站长微信 710 342 444 或者扫一扫右侧二维码。
    0 条回复 A文章作者 M管理员
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    有新私信 私信列表
    搜索