C#的编译模型可以把一个项目中的所有源文件看成一个逻辑代码体, 而且声明与使用的顺序可以是任意的, 这句话却模糊了#define 这样的"预处理"方法的作用范围.
# 只能在一个.cs源文件的最开头使用#define
# 不能象C语言中一样指定一个宏可以替换为其它内容, 更不能定义C中的函数式宏
# 一个.cs源文件中通过#define定义的宏符号要么是defined, 要么是undefined状态, 直到遇到#undef 预处理指令, #define 同一个宏符号可以多次出现, 但只能位于文件开关
# 通过#define在文件中显式定义的宏作用范围仅限于当前文件本身.
通过最后一个特性, 可以在代码中构建出一个永远能得到执行的Assert语句, 如下:
/* This file only defines two Assert method, whose purpose is to ensure always assert whatever DEBUG
* and TRACE is defined in project setting or not, the explicit #define will only affect this file only
* Please DO NOT put other code in this file, keep it single purpose!
*/
#define DEBUG
using System;
using System.Diagnostics;
namespace MyCompany
{
partial class AppOptions
{
public static void Assert(bool is_true)
{
Assert(is_true, string.Empty);
}
public static void Assert(bool is_true, string errmsg)
{
if (s_is_force_assert == null)
{
s_is_force_assert = IsAppSettingTrue("force_assert");
}
if (s_is_force_assert == true)
Debug.Assert(is_true, errmsg);
else
{
log.Error(errmsg);
}
}
}
}
|
这里使用了另一个C#2.0中的特性: partial class, 通过这一手段, 可以把强制定义的DEBUG宏的影响限定在一个小文件内, 仅作此用途. 如此无论是否定义 DEBUG宏, 这个文件中的Debug.Assert都会得到执行.
不记得在哪本书里看到的, 说关于assert的使用, 最糟糕的莫过于在产品代码(Release版)中去掉断言了. 也许这个说法是有争议的, 不过我的确需要不论如何都要弹出错误警告的Assert, 及早, 大声地报告错误比掩盖错误要好.
作为对partial class的一个延伸, 我想partial class至少有以下三个合理的应用(有人不鼓励使用partial class)
1. VS.Studio 中Form Designer 自己生成的代码, 微软在用
2. 使用#region ... #endregion把一个类内部相关的一片代码隔离开来, 同样也可以把这段代码放在一个partial class的片断定义中
3. 就是这里因为特殊原因要把宏定义对一个类中小部分代码的影响作用孤立出来.
阅读(1604) | 评论(0) | 转发(0) |