IMO 区分#if 和#define 很重要。两者都可能有用,也都可能被过度使用。我的经验是#define 比#if 更容易被过度使用。
我花了 10 多年的时间做 C 和 C++ 编程。在我从事的项目(DOS / Unix / Macintosh / Windows 的商业可用软件)中,我们主要使用#if 和#define 来处理代码可移植性问题。
我花了足够的时间使用 C++/MFC 来学习如何在过度使用 #define 时厌恶它——我相信 1996 年左右的 MFC 就是这种情况。
然后我花了 7 年多的时间从事 Java 项目。我不能说我错过了预处理器(尽管我肯定错过了 Java 当时没有的枚举类型和模板/泛型之类的东西)。
自 2003 年以来,我一直在使用 C#。我们在调试版本中大量使用了 #if 和 [Conditional("DEBUG")] - 但 #if 只是一种更方便、更有效的方法我们在 Java 中所做的事情。
展望未来,我们已经开始为 Silverlight 准备我们的核心引擎。虽然我们所做的一切都可以在没有#if 的情况下完成,但使用#if 可以减少工作量,这意味着我们可以花更多时间添加客户要求的功能。例如,我们有一个值类,它封装了系统颜色以存储在我们的核心引擎中。下面是前几行代码。由于 System.Drawing.Color 和 System.Windows.Media.Color 之间的相似性,顶部的#define 为我们提供了普通 .NET 和 Silverlight 中的许多功能,而无需重复代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
#if SILVERLIGHT
using SystemColor = System.Windows.Media.Color;
#else
using SystemColor = System.Drawing.Color;
#endif
namespace SpreadsheetGear.Drawing
{
/// <summary>
/// Represents a Color in the SpreadsheetGear API and provides implicit conversion operators to and from System.Drawing.Color and / or System.Windows.Media.Color.
/// </summary>
public struct Color
{
public override string ToString()
{
//return string.Format("Color({0}, {1}, {2})", R, G, B);
return _color.ToString();
}
public override bool Equals(object obj)
{
return (obj is Color && (this == (Color)obj))
|| (obj is SystemColor && (_color == (SystemColor)obj));
}
...
对我来说,底线是有很多语言特性可以被过度使用,但这并不足以成为将这些特性排除在外或制定严格规则禁止使用它们的充分理由。我必须说,在用 Java 编程这么久之后转向 C# 帮助我欣赏这一点,因为微软 (Anders Hejlsberg) 更愿意提供可能不吸引大学教授的功能,但这些功能让我在工作中更有效率并最终使我能够在任何有发货日期的人的有限时间内构建一个更好的小部件。