在构建期间替换代码部分就像c ++中的旧的#define一样

时间:2014-08-14 11:44:47

标签: c# operator-overloading operators

我们正在寻找一种向我们的解决方案添加NOT运算符的方法。不幸的是,C#不支持新的运算符,所以我们不能只将NOT添加为新运算符。

接下来我们想到的是实现一个静态方法NOT()。但此时,C#不支持使用Namespace.StaticTypeName; (至少我们还没想到它) - 这就是为什么我们必须一直写下愚蠢的类名。

然后我们终于有了用@ -Operator替换NOT的想法,每次我们构建解决方案时...就像c ++中的旧#define一样。

在C#中可以吗?

5 个答案:

答案 0 :(得分:2)

你不能用普通的旧C#进行预处理。

但如果您愿意创建自己的C#",则可以在编译之前使用Roslyn为您在语法树上进行转换。

可以在response to this question中看到这种转变的例子。

但是,我建议不要采用这种做法:除了你自己的团队之外,几乎所有人都会使你的代码不那么可读,使你的构建过程变得更加复杂,需要对你添加到团队中的人进行特定的培训,可能打破大多数静态分析仪。

您还可以通过以下方式获得结果:

答案 1 :(得分:1)

C#中没有预处理,所以你不能将#defines用于你想要的东西。

您可以尝试使用这样的扩展方法:

public static T Not<T>(this T) {
    // your logic here
    return ...
}

并像这样使用它:

... || myvar.Not() + ...

这样你就不需要在声明扩展方法的地方使用类名,但你仍然需要为包含扩展方法声明的类的命名空间添加using MyNamespace;

答案 2 :(得分:1)

正如您所注意到的,您无法在C#中创建新的运算符。 .NET确实公开了编译器类,因此您可以自行编译,在处理它们之前替换这些值。

如果你想继续遵守C#,Lanorkin分享的扩展方法解决方案可能是最好的。另一个“解决方案”是无名称空间的静态Not类:

public struct Not
{
    public Not(bool value)
        : this()
    {
        NotValue = !value;
    }

    public bool NotValue
    {
        get;
        private set;
    }

    public static implicit operator bool(Not value)
    {
        return value.NotValue;
    }
}

bool trueValue = new Not(false);

对于您的新员工,这也清楚地表明运营商是新运营商,而不是C#运营商。

您的整个团队是否认为感叹号会影响可读性?他们都有一个很好的旧c ++背景吗?你的if陈述有多大?您是否考虑过交换ifelse部分以减少首先需要not ting?

如果我开始为贵公司工作,我需要几个月才能忘记感叹号。

答案 3 :(得分:0)

在评论中作出一些澄清之后,我听到你说错了。

请不要尝试为!之类的琐碎操作创建函数。这不仅会使您的代码与新人不理解的东西混乱,如果没有内联方法,也会损害您的性能。

答案 4 :(得分:0)

扩展方法是一种很好的方法:

public static class Extensions
{
    public static bool NOT(this bool flag)
    {
        return !flag;
    }
}

因此无论您在代码中的哪个位置,都可以调用someBool.NOT();

如果您绝对只想将其称为NOT(someBool),那么就这样做:

public static class Extensions
{
    public static bool NOT(this object ignored, bool flag)
    {
        return !flag;
    }
}