C# 如何重新定义C中标准关键字的名称#
我有一个有趣的想法。我想重新定义C#中的关键字,比如将C# 如何重新定义C中标准关键字的名称#,c#,c-preprocessor,C#,C Preprocessor,我有一个有趣的想法。我想重新定义C#中的关键字,比如将if关键字替换为MyIf或其他内容。有人知道怎么做吗 因为我认为它必须看起来像这样: namespace { #define MyIf = if; #define MyElse = else; ... public someclass { public void someMethod() { MyIf(true) {
if
关键字替换为MyIf
或其他内容。有人知道怎么做吗
因为我认为它必须看起来像这样:
namespace
{
#define MyIf = if;
#define MyElse = else;
...
public someclass
{
public void someMethod()
{
MyIf(true)
{
...
}
MyElse
{
...
}
}
}
}
添加:
< >也许有办法使C++或<强> c>强>库重新定义C核的标准核部分?
**注意。我知道这是一种糟糕的编程实践,我要求所有程序员不要在企业代码中使用这个答案**>这是不可能的——C语言没有预处理器,如C和C++,所以在编译器看到之前没有转换源的机制。当然,编译器只会识别标准的if
,因此也没有其他选项可以在编译器看到源代码之前以某种方式转换源代码
即使这是可能的,在恐怖程度上也只比Cthulhu低一步。你不能重新定义
if
或else
,因为C#没有一个预处理器可以让你做那样的事情(可能也可以防止任何人做那样的事情)
但您可以重新定义类的实例何时计算为true
/false
(这是您可以得到的最接近的值):
例如:
YourType wah = new YourType() { IsLying = true, Whatever = true };
if (wah) {
// ...
}
else {
// ...
}
有关更多详细信息,请参见此处:在c语言中,您可以覆盖可重载运算符(+,-,==),更多信息请参见: 但是您不能真正覆盖条件运算符 这些运算符=,,,?:,->,new,is,sizeof,typeof也是如此,它们不能重载 C#不支持宏,但在最终将代码发送到C#编译器之前,您当然可以编写一个处理宏的自定义解析器,请查看Microsoft Roslyn 在C#中,预处理器指令用于有条件编译代码
#define
用于定义符号。使用符号作为传递给#if
指令的表达式时,表达式将
评估为真
执行类似于所需的操作,可以覆盖隐式布尔运算符:
using System;
class PleaseDontDoThis {
public static implicit operator bool(PleaseDontDoThis h) {
return (new Random().Next() % 2 == 0);
}
}
static class Program {
static void Main(string[] args) {
var x = new PleaseDontDoThis();
if (x) {
Console.WriteLine("true");
} else {
Console.WriteLine("false");
}
}
}
#
#define允许您定义符号,这样,通过使用符号作为传递给#if指令的表达式,表达式的计算结果将为true
C#没有a,但它有相似的指令:
尽管编译器没有单独的预处理器,但本节中描述的指令的处理方式与预处理器相同。它们用于帮助条件编译<与C和C++指令不同,不能使用这些指令创建宏<强> > /p>
这不是C++中定义的相同的定义,或者C .c’i只定义了存在一个文字但没有该文本的替换或宏的状态。
#define STRING int // Valid in C++ but invalid in C#
C++ define指令用令牌字符串替换源文件中随后出现的所有标识符。仅当标识符形成令牌时,才会替换该标识符。(参见C++语言引用中的C++标记)。例如,如果标识符出现在注释中、字符串内或作为较长标识符的一部分,则不替换标识符。
您可以将单子与
扩展方法一起使用,例如
这可能是莫纳德
public static TInput If<TInput>(this TInput o, Predicate<TInput> evaluator)
where TInput : class
{
if (o == null) return null;
return evaluator(o) ? o : null;
}
public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator, TResult failureValue)
where TInput : class
{
if (o == null) return failureValue;
return evaluator(o);
}
不要那样做。这使得你的代码无法维护。这是一个有趣的问题,你为什么需要你自己的,如果?如果
您不能,它应该做什么不同于标准。C#不支持任何形式的宏。这可能是不可能的,因为这是个坏主意。你在C#中错了,有一个预处理器:@Maris:preprocessor指令并不意味着C#有一个预处理器。@Maris:你链接到的页面上说“尽管编译器没有单独的预处理器,但本节中描述的指令的处理方式与预处理器相同。“哦,是的。我错过了。让我们看看如何做的其他想法。)也许有人有主意。@Maris:就像我在评论中说的,Nemerle可以做到这一点。Nemerle甚至可以编译普通的C代码。为什么是自定义解析器或Roslyn?我认为简单的查找/替换与C#一样好。查找/替换并不总是一个好的解决方案,roslyn真的很容易使用,所以我会使用它。我编写了一些从10GB TFS集合中提取sql查询的代码,我花了20分钟编写代码,我的程序花了几分钟提取查询。在Roslyn解析它之前,您必须将MyIf
更改为if
。那么它将与C#一样。那你打算怎么处置罗斯林呢?我收到你的评论,我只是不理解Roslyn在这个问题上的使用案例。正如我之前所说的,查找/替换不是一个好的解决方案,不知道是否只有我,但我不喜欢这种方法。在使用Roslyn时,我可以告诉它在方法体或使用声明中查找特定代码,我可以更具体一些。。我认为这是一个好主意。我不知道没有工作的例子,但我相信有人也做过。我也写过很多编译器,每天都在使用cil和c#编译器,所以我对此也很现实。祝你度过愉快的一天。这看起来不像这个问题的答案。但我喜欢这个主意。谢谢谢谢,这是从Monad的想法中取出来的,如果你喜欢,我可以把整个班级都贴出来,请贴出来。我认为这对很多人都是有用的。再次感谢。
public static TInput If<TInput>(this TInput o, Predicate<TInput> evaluator)
where TInput : class
{
if (o == null) return null;
return evaluator(o) ? o : null;
}
public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator, TResult failureValue)
where TInput : class
{
if (o == null) return failureValue;
return evaluator(o);
}
var result = ListOfObjects.If(o => o.Id == 1).Return(x => x.Object, null);