Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么不';C#中没有宏吗?_C#_.net_Macros_C Preprocessor - Fatal编程技术网

为什么不';C#中没有宏吗?

为什么不';C#中没有宏吗?,c#,.net,macros,c-preprocessor,C#,.net,Macros,C Preprocessor,当我第一次学习C#时,我感到惊讶的是,他们不支持与C/C++中相同容量的宏。我意识到#define关键字存在于C#中,但与我在C/C++中逐渐喜欢的东西相比,它非常缺乏。有人知道为什么C#中缺少real宏吗 如果这个问题已经以某种形式被问到了,我很抱歉-我保证在发布之前我花了整整5分钟寻找副本。C++风格的宏增加了大量的复杂性,但在我的经验中没有相应的好处。在C#或Java中,我当然没有错过它们。(我很少在C#中使用预处理器符号,但有时我很高兴它们在那里。) 现在各种各样的人都在呼吁,我对此知之

当我第一次学习C#时,我感到惊讶的是,他们不支持与C/C++中相同容量的宏。我意识到#define关键字存在于C#中,但与我在C/C++中逐渐喜欢的东西相比,它非常缺乏。有人知道为什么C#中缺少real宏吗


如果这个问题已经以某种形式被问到了,我很抱歉-我保证在发布之前我花了整整5分钟寻找副本。

C++风格的宏增加了大量的复杂性,但在我的经验中没有相应的好处。在C#或Java中,我当然没有错过它们。(我很少在C#中使用预处理器符号,但有时我很高兴它们在那里。)

现在各种各样的人都在呼吁,我对此知之甚少,但听起来肯定比C++风格的更令人愉快

您特别希望如何处理宏?我们可能会帮助您以更惯用的C#方式思考…

来自C#faq

为什么C不支持定义宏? 在C++中,我可以定义一个宏,例如:

#定义产品(x,y,z)x*y*z

然后在代码中使用它:

inta=产品(3,2,1)

C#不允许你这么做。为什么?

原因有几个。第一个是可读性

C#的主要设计目标之一是保持代码的可读性。拥有编写宏的能力使程序员能够创建自己的语言——一种不一定与下面的代码有任何关系的语言。要理解代码的功能,用户不仅必须理解语言的工作原理,还必须理解当时生效的所有#define宏。这使得代码更难阅读

在C#中,您可以使用方法而不是宏,并且在大多数情况下,JIT将内联它们,从而提供相同的性能方面

还有一个更微妙的问题。宏是以文本方式完成的,这意味着如果我编写:

int y=产品(1+2、3+4、5+6)

我希望得到的东西能给我提供
3*7*11=231
,但事实上,我定义的扩展提供了:

inty=1+2*3+4*5+6

这给了我33分。我可以通过明智地应用括号来解决这个问题,但是编写一个在某些情况下工作而在其他情况下不工作的宏是非常容易的

虽然严格来说C#没有前置处理器,但它确实有条件编译符号,可以用来影响编译。这些可以在代码中定义,也可以使用编译器的参数来定义。C#中的“预处理”指令(仅因与C/C++的一致性而命名,尽管没有单独的预处理步骤)是(文本取自ECMA规范):

#定义和#取消定义
用于定义和取消定义条件编译符号

#if、#elif、#else和#endif

用于有条件地跳过源代码的部分

#行
用于控制针对错误和警告发出的行号

#错误和#警告
用于发出错误和警告

#区域和#结束区域

用于显式标记源代码的各个部分

有关上述内容的更多信息,请参见ECMA规范第9.5节。条件编译也可以使用方法上的Conditional属性来实现,因此只有在定义了适当的符号时才会编译对该方法的调用。有关这方面的更多信息,请参见ECMA规范第24.4.2节

作者:Eric Gunnerson


宏在C/C++中被用来定义常量,产生小的内联函数,以及直接与编译代码有关的各种事物(μiIFDEF)。p> 在C#中,您拥有强类型常量,一个足够聪明的编译器,可以在必要时内联函数,并且知道如何以正确的方式编译内容(没有预编译头的废话)


但是如果你真的想,没有什么特别的原因让你不能首先通过C预处理器运行你的CS文件:)

宏在C++
中被过度使用,但它们仍然存在,然而,由于反射和更好地集成使用异常进行错误报告,这些用法中的大多数与
C#
无关。

在大多数程序员比编译器更聪明的年代,宏是一种工具。在C/C++中,仍有一些情况是这样的


现在,大多数程序员都不如C#编译器/运行时那么聪明。

本文比较了perl和lisp宏,但要点仍然是一样的:与源代码级宏(lisp)相比,文本级宏(perl/C++)会导致大量问题


比我勇敢的人已经在c#

中推出了他们自己的类似宏的系统,这样你就可以一次又一次地输入这些内容

// 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));
}
显然,C#和.NET的设计者从未真正使用过他们创建的任何库或框架。如果他们这样做了,他们就会意识到某种形式的卫生句法宏观系统肯定是有序的

不要让C和C++的蹩脚宏的缺点使您对编译时解析代码的能力感到厌烦。编译时解析和代码生成允许您更有效地表达代码的含义和意图,而无需详细说明源代码的所有琐碎细节。例如,如果您可以将上述内容替换为:

public class MyStateControl : ButtonBase
{
  public MyStateControl() : base() { }

  [DependencyProperty(DefaultValue=true)] 
  bool State { get; set; }
}
<嘘有他们,OcamML(至少Meta ML)有他们,C和C++有他们(以一种恶劣的形式,但比没有他们好)。C<不。

C针对的是更广泛的受众(或在其他术语中,消费者基础),而不是C++、C或ASM。实现这一目标的唯一途径

protected int _PropOne;
public int PropOne
{
    get
    {
        return _PropOne;
    }
    set
    {
        if(value == _PropOne) { return; }
        NotifyPropertyChanging("PropOne");
        _PropOne = value;
        NotifyPropertyChanged("PropOne");
    }
}
DECLARE_PROPERTY(int, PropOne)
DECLARE_PROPERTY(string, PropTwo)
DECLARE_PROPERTY(BitmapImage, PropThree)