定义一个部门类,三个字段,部门ID,部门名称,部门备注,分别创建对应的属性,在属性的赋值语句中做些参数逻辑的检查。同时有三个构造函数,很多人和很多书上在构造函数里直接将参数赋值给类内部的私有字段,我认为这样,在别人用这个类来new一个对象时,有可能将不对的参数传进来,于是我在构造函数里直接将参数赋值给属性,代码如下,可同时带来麻烦,例如部门字段,当我更新建一条记录时,(备注可以为空,名称不能为空),就出现了错误 未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。源错误:行 62:         set 
行 63:         {
行 64:             if (value.Length > 4000)
行 65:                 throw new ArgumentException("备注不能大于4000个字符");
行 66:             public class Department
{
    private int _id = 0;
    private string _departmentName = string.Empty;
    private string _reMark=string.Empty;
    public int ID
    {
        get { return _id; }
        set
        {
            if (value < 1)
                new ArgumentException("部门ID不能小于1!");            _id = value;
        }
    }
    public string DepartmentName
    {
        get { return _departmentName; }
        set
        {
            if (string.IsNullOrEmpty(value))
                throw new ApplicationException("部门名称不能为空!");            if (value.Length > 50)
                throw new ApplicationException("部门名称不能超过50个字符!");            _departmentName = value;
        }
    }
    public string ReMark
    {
        get { return _reMark; }
        set 
        {
            if (value.Length > 4000) 
                throw new ArgumentException("备注不能大于4000个字符");
            
            _reMark = value; 
        }
    }    public Department(int id, string departmentName, string re)
    {
        ID = id;
        DepartmentName = departmentName;
        ReMark = re;
    }  
    
    public Department(string departmentName, string re)
        : this(0, departmentName, re)
    {
    }    public Department()
    {
    }该如何设计?

解决方案 »

  1.   

    在调用这个类前,应该对传进来的参数进行是否正常检查,也就是说应该在调用该类的文件里检查,在这里检查不合适如果在这里检查,那就要允许他可以是null的
      

  2.   

    如果是在调用前检查,那属性还有存在的意义吗?  是否可以写成
         
       public string ReMark
        {
            get { return _reMark; }
            set
            {
               if( Convert.IsDBNull(value) )
                   _reMark=String.Empty;           else if (value.Length > 4000)
                    throw new ArgumentException("备注不能大于4000个字符");
                _reMark = value;
            }
        } 
      

  3.   

    根据具体情况
    如果是自己使用的类库,为了快速开发可以直接赋值给property, 但是property set可不用处理
        public int ID
        {
            get 
            {
                return _id; 
            }
            set
            {
                _id = value;
            }
        }
    也方便以后的refactor如果是开发,比如说API,就要对所有的传入数据进行严格校验另外,建议是使用customized Exception,使对Exception处理更灵活
      

  4.   

        是否可以写成 
              
          public   string   ReMark 
            { 
                    get   {   return   _reMark;   } 
                    set 
                    { 
                          if(   Convert.IsDBNull(value)   ) 
                                  _reMark=String.Empty;                       else   if   (value.Length   >   4000) 
                                    throw   new   ArgumentException( "备注不能大于4000个字符 "); 
                            _reMark   =   value; 
                    } 
            }   你可以这么写,但最好不要这么写,检查数值不应该在这里,因为不利于代码复用
    举个例子,下次,你又要掉这个函数,但这个函数的length偏偏超过了4000,而且还是正常的,怎么办?改这里吗?
    改这里又破坏了以前的大于4000的这个逻辑。
      

  5.   

    晕,早上刚试 未将对象引用设置到对象的实例。
    说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。源错误:行 62:         set 
    行 63:         {
    行 64:             if (Convert.IsDBNull(value))
    ..................
      

  6.   

    up,如何判断?
    if (Convert.IsDBNull(value)|| value == null) 也提示一样的错误 
    未将对象引用设置到对象的实例。
      

  7.   

    我认为这样,在别人用这个类来new一个对象时,有可能将不对的参数传进来
    ------------
    “你认为”的属于多管闲事...oo中很重要的一点是...各人自扫门前雪休管他人瓦上霜...明确职责...
      

  8.   

    我记的Beginning C# Objects 中也建议在有参数的构造函数中将参数附到属性上。有利于数据的验证,
    当然默认的构造函数将私有字段赋默认值。当然这是个人的习惯。可现在的问题是无论如何判断(在属性和在方法里)老是提示未将对象引用设置到对象的实例。
    说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。源错误:行 62:        set
    行 63:        {
    行 64:            if ( Convert.IsDBNull(value) ¦ ¦ value==null )
    ..................
    属性和方法如下:
    public string ReMark
        {
            get { return _reMark; }
            set
            {
                if(  Convert.IsDBNull(value) ¦ ¦ value==null )
                      _reMark=String.Empty;            else  if  (value.Length  >  4000)
                        throw  new  ArgumentException( "备注不能大于4000个字符 ");
                         
                _reMark  =  value;
            }
        } 
    /// <summary>
        /// 创建一个新部门
        /// </summary>
        /// <param name="depName"> </param>
        /// <param name="re"> </param>
        public void Insert(string departmentName, string ReMark)
        {
            if (string.IsNullOrEmpty(ReMark))
                ReMark = string.Empty;        Department dep = new Department(departmentName, ReMark);
            DALDepartment daldep = new DALDepartment();//创建数据层
            daldep.InsertDepartment(dep);
        } 
      

  9.   

    if(  Convert.IsDBNull(value) ¦ ¦ value==null ) 改成string.isnullorempty(value)
    试试?
      

  10.   

    刚才我试过了,类应该没有问题,如下测试,备注为空也没有问题,能正常添加记录  <div> <asp:TextBox ID="TextBox1" runat="server"> </asp:TextBox> <br />
            <asp:TextBox ID="TextBox2" runat="server"> </asp:TextBox>
            <asp:Button ID="Button4" runat="server" Text="Button" onclick="Button4_Click" />
            <br /> </div>
    protected void Button4_Click(object sender, EventArgs e)
            {
                Department d = new Department();
                d.Insert(TextBox1.Text, TextBox2.Text);
            }不知道为什么一绑定到数据源,GridView,DetailesView,平时操作没有问题,当把一些可为空的数据置空更新就出显上面的错误