大家都知道,通常在编译程序时可以选择Debug版本还是Release版本,编译器将会根据”调试“和”发布“两个不同的出发点去编译程序。在Debug版本中,所有Debug类的断言(Assert)语句都会得到保留,相反在Release版本中,则会被通通删除。这样的机制有助于我们编写出方便调试同时又不影响正式发布的程序代码。.
But,单纯的诊断和断言可能并不能完全满足测试的需求,有时可能会需要大批的代码和方法去支持调试和测试,这个时候就需要用到Conditional特性。Conditional特性用于编写在某个特定版本中运行的方法,通常它编写一些在Debug版本中支持测试的方法。当版本不匹配时,编译器会把Conditional特性的方法内容置为空。
下面的一段代码演示了Conditional特性的使用:
//含有两个成员,生日和身份证
//身份证的第6位到第14位必须是生日
//身份证必须是18位
public class People
{
private DateTime _birthday;
private String _id;
public DateTime Birthday
{
set
{
_birthday = value;
if (!Check())
throw new ArgumentException();
}
get
{
Debug();
return _birthday;
}
}
public String ID
{
set
{
_id = value;
if (!Check())
throw new ArgumentException();
}
get
{
Debug();
return _id;
}
}
public People(String id, DateTime birthday)
{
_id = id;
_birthday = birthday;
Check();
Debug();
Console.WriteLine("People实例被构造了...");
}
// 只希望在DEBUG版本中出现
[Conditional("DEBUG")]
protected void Debug()
{
Console.WriteLine(_birthday.ToString("yyyy-MM-dd"));
Console.WriteLine(_id);
}
//检查是否符合业务逻辑
//在所有版本中都需要
protected bool Check()
{
if (_id.Length != 18 ||
_id.Substring(6, 8) != _birthday.ToString("yyyyMMdd"))
return false;
return true;
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
People p = new People("513001198811290215", new DateTime(1988, 11, 29));
p.ID = "513001198811290215";
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.GetType().ToString());
}
Console.ReadKey();
}
}
下图则展示了上述代码在Debug版本和Release版本中的输出结果:
① Debug版本:
② Release版本:
Conditional机制很简单,在编译的时候编译器会查看编译状态和Conditional特性的参数,如果两者匹配,则正常编译。否则,编译器将简单地移除方法内的所有内容。