And*_*son 48 .net c# macros c-preprocessor
在第一次学习C#时,我很惊讶他们不支持与C/C++相同容量的宏.我意识到#define关键字存在于C#中,但与我在C/C++中的喜爱相比,它非常缺乏.有谁知道为什么C#中缺少真正的宏?
如果这个问题已经以某种形式提出,我很抱歉 - 我保证在发布前花了5分钟时间寻找重复的问题.
Dou*_*asH 67
来自C#faq.
http://blogs.msdn.com/CSharpFAQ/archive/2004/03/09/86979.aspx
为什么C#不支持#define宏?在C++中,我可以定义一个宏,例如:
#define PRODUCT(x, y, z) x * y * z然后在代码中使用它:
int a = PRODUCT(3, 2, 1);C#不允许你这样做.为什么?
有几个原因.第一个是可读性.
我们对C#的主要设计目标之一是保持代码的可读性.具有编写宏的能力使程序员能够创建自己的语言 - 这种语言不一定与下面的代码有任何关系.要理解代码的作用,用户不仅必须了解语言的工作方式,还必须了解当时有效的所有#define宏.这使得代码更难阅读.
在C#中,您可以使用方法而不是宏,并且在大多数情况下,JIT将内联它们,为您提供相同的性能方面.
还有一个更微妙的问题.宏以文本方式完成,这意味着如果我写:
int y = PRODUCT (1 + 2, 3 + 4, 5 + 6)我希望能得到一些东西给我
3 * 7 *11 = 231,但实际上,我所定义的扩展给出了:
int y = 1 + 2 * 3 + 4 * 5 + 6;这给了我33.我可以通过明智的括号应用来解决这个问题,但很容易编写一个在某些情况下工作而不在其他情况下工作的宏.
虽然C#严格来说没有预处理器,但它确实有条件编译符号可用于影响编译.这些可以在代码中定义,也可以在编译器的参数中定义.C#中的"预处理"指令(仅为与C/C++的一致性命名,尽管没有单独的预处理步骤)是(来自ECMA规范的文本):
#define and #undef用于定义和取消定义条件编译符号
#if, #elif, #else and #endif用于有条件地跳过部分源代码
#line用于控制为错误和警告发出的行号.
#error and #warning用于发出错误和警告.
#region and #endregion用于显式标记源代码的各个部分.
有关上述内容的更多信息,请参阅ECMA规范的第9.5节.也可以使用方法上的Conditional属性来实现条件编译,以便只有在定义了适当的符号时才会编译对方法的调用.有关详细信息,请参阅ECMA规范的第24.4.2节.
作者:Eric Gunnerson
小智 36
这样你就可以一遍又一遍地打字.
// Windows presetation foundation dependency property.
public class MyStateControl : ButtonBase
{
public MyStateControl() : base() { }
public Boolean State
{
get { return (Boolean)this.GetValue(StateProperty); }
set { this.SetValue(StateProperty, value); }
}
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
"State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false));
}
Run Code Online (Sandbox Code Playgroud)
显然,C#和.NET的设计者实际上从未使用他们创建的任何库或框架.如果他们这样做了,他们就会意识到某种形式的hygenic句法宏观系统肯定是有序的.
不要让C和C++的蹩脚宏的缺点让你厌倦了编译时解析代码的力量.编译时间分辨率和代码生成使您可以更有效地表达代码的意义和意图,而无需详细说明源代码的所有细节.例如,如果您可以用以下内容替换上面的内容:
public class MyStateControl : ButtonBase
{
public MyStateControl() : base() { }
[DependencyProperty(DefaultValue=true)]
bool State { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Boo有它们,OcamML(至少是Meta ML)有它们,而C和C++有它们(以一种讨厌的形式,但总比没有它们好).C#没有.
与C++,C或ASM相比,C#面向更广泛的受众(或其他术语,消费者群体).实现这一目标的唯一方法是让程序员接受相当不熟练的技能.因此,所有强大但危险的工具都被带走了.即宏,多重继承,对对象生命周期的控制或类型无关的编程.
以同样的方式匹配,刀和钉枪是有用和必要的,但它们必须远离儿童.(遗憾的是,纵火,谋杀,内存泄漏和不可读的代码仍然会发生).
在指责我不考虑C#之前,有多少次你写过:
protected int _PropOne;
public int PropOne
{
get
{
return _PropOne;
}
set
{
if(value == _PropOne) { return; }
NotifyPropertyChanging("PropOne");
_PropOne = value;
NotifyPropertyChanged("PropOne");
}
}
Run Code Online (Sandbox Code Playgroud)
使用宏,每次这16行看起来像这样:
DECLARE_PROPERTY(int, PropOne)
DECLARE_PROPERTY(string, PropTwo)
DECLARE_PROPERTY(BitmapImage, PropThree)
Run Code Online (Sandbox Code Playgroud)
C / C++ 中的宏用于定义常量、生成小型内联函数以及与编译代码直接相关的各种操作 (#ifdef)。
在 C# 中,您拥有强类型常量、足够智能的编译器,可以在必要时内联函数,并且知道如何以正确的方式编译内容(没有预编译头废话)。
但是,如果您确实想要的话,没有什么特殊原因不能首先通过 C 预处理器运行 CS 文件:)