警惕缺省参数(Optional Parameters)对类型(Type)构造函数(Constructor)设计的影响
缺省参数(Optional Parameters)是编译器的一个语法糖,有时这种看似自然的调用会将类型设计引入一个误区。看一个例子:
/// <summary> /// 响应消息 /// </summary> public class ResponseMessage { /// <summary> /// 构造函数 /// </summary> /// <param name="status">状态</param> /// <param name="message">消息</param> /// <param name="data">数据</param> public ResponseMessage(Int32 status = 1, String message = "", Object data = null) { this.Status = status; this.Message = message; this.Data = data; } /// <summary> /// 状态 /// </summary> public Int32 Status { get; set; } /// <summary> /// 消息 /// </summary> public String Message { get; set; } /// <summary> /// 数据 /// </summary> public Object Data { get; set; } }
形似构造函数的调用如下:
ResponseMessage message = new ResponseMessage(); message = new ResponseMessage(1); message = new ResponseMessage(1, "Hello world"); message = new ResponseMessage(1, "Hello world", Int32.MaxValue);
在类型元数据中,实际只定义一个有3个参数的构造函数:{Void .ctor(Int32, System.String, System.Object)}。ResponseMessage由于缺省参数的使用,完全不需要一无参构造函数就可以变出看似4个构造函数的重载。这时对于一些Serializer就无法真正的调用无参构造函数,看一个例子:
ResponseMessage message = new ResponseMessage(); JavaScriptSerializer serialzier = new JavaScriptSerializer(); String json = serialzier.Serialize(message); message = serialzier.Deserialize<ResponseMessage>(json);
上面的代码在反序列化时会抛出MissingMethodException,并提示:No parameterless constructor defined for type of 'ResponseMessage'.因为ResponseMessage并没有真正的无参构造函数。