获取对象引用未设置为实例

时间:2013-02-02 23:57:06

标签: c# oop

    [DataContract]
        [Serializable]
        public class WSAccount
        {
            [DataMember]
            public string AccountNumber { get; set; }
            [DataMember]
            public string Pin { get; set; }        
        }

 [DataContract]
    [Serializable]
    public class WSUser
    {
       [DataMember]
        public WSAccount wsAccount { get; set; }
        [DataMember]
        public bool IsValidUser { get; set; }
    }

执行

时出错
WSUser user = new WSUser();
 user.wsAccount.AccountNumber = userNameresponse.account.ID;

但在

时解决了
 WSUser user = new WSUser();
 user.wsAccount = new WSAccount();
 user.wsAccount.AccountNumber = userNameresponse.account.ID;

我是否需要实例化子类WSAccount ??

3 个答案:

答案 0 :(得分:1)

是的,如果您想访问其中的任何属性或方法,则需要wsAccount成为有效WSAccount(例如,不是null)。默认情况下,它被初始化为null,这是任何对象引用的默认值。

您当然可以在WSUser的构造函数中初始化它,例如:

public WSUser() {
    wsAccount = new WSAccount();
}

最有可能的是,您不能或不想这样做,因为您可能希望单个WSAccount被多个其他实例(其他类)使用。将帐户作为参数传递给WSUser构造函数,或让调用者在构造之后设置它。前者可能更可取,因为你的构造函数可以对输入进行一些健全性检查,你不能忘记在构造之后设置帐户(因为构造函数强制你事先传递一个)。

答案 1 :(得分:1)

是的,你这样做。

这是因为你的默认构造函数(如果没有重新定义,而不是)则对它所拥有的每个字段或自动属性使用默认值。意思是,每个int都将'0'作为值,每个引用类型(wsAccount) - null。

所以你必须将wsAccount属性实例化为正确的对象,否则它是null。

答案 2 :(得分:1)

所有类型都有默认值:

  • 引用类型(包括字符串)=>空

  • 值类型=> (int => 0,float => 0,Guid => Guid.Empty等。)

这就是您需要显式实例化WSAccount类的原因。 您还可以在WSUser的构造函数中实例化WSAccount

public WSUser()
{
  this.wsAccount = new WSAccount();
}

或者你可以懒加载wsAccount

private WSAccount _wsAccount;

public WSAccount WsAccount
{
  get 
  { 
    if (_wsAccount==null)
      _wsAccount= new WSAccount();
    return _wsAccount;
  }
  set { _wsAccount = value }            
}

最后,

您可以使用C#4.0提供的Lazy<T>实现延迟加载的变量

但是,在反序列化期间,反序列化器将在引擎盖下调用默认构造函数,然后相应地设置属性,因此执行此操作:

WSUser user = new WSUser();
user.wsAccount = new WSAccount();
user.wsAccount.AccountNumber = <value>