0

We are looking for a way to add an NOT Operator to our solutions. Unfortunately, C# doesnt support new operators, so we couldnt just add NOT as a new Operator.

Next thing we thought of was implementing a static method NOT(). But at this moment, C# doesnt support using Namespace.StaticTypeName; (atleast we havent figured it out yet) - Thats why we would have to write down the silly classname all the time.

Then we had finally the idea to replace the NOT with the !-Operator, every time we build the solution... like the good old #define in c++.

Is it possible in C#?

fubo
  • 44,811
  • 17
  • 103
  • 137
Jannik
  • 2,310
  • 6
  • 32
  • 61

5 Answers5

2

You cannot have preprocessing in plain old C#.

But if you're willing to create "your own C#", you can use Roslyn to make the transformations on the syntactic tree for you before compiling it.

An exemple of such a transformation can be seen in the response to this question.

However, I would advise against this kind of practice: it makes your code less readable for pretty much everybody except your own team, makes your build process more complicated, requires a specific training for the people you add to your team and is likely to break most of the static analysers.

You can also achieve your result with the following:

Community
  • 1
  • 1
Falanwe
  • 4,636
  • 22
  • 37
  • @PatrickHofman: exactly. You can, but don't do it for such trivial things. However, DO use Roslyn as a preprocessor to automatically implement complex and repetitive logic on some classes. For instance, observable properties on ViewModels in MVVM are a pain to write on every single. Create an attribute and let Roslyn rewrie the properties for you. – Falanwe Aug 14 '14 at 12:17
1

There's no preprocessing in C#, so you cannot use #defines for what you want.

You can try using extension methods like this:

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

And use it like this:

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

This way you needn't to use class name where extension method is declared, but you will still need to add using MyNamespace; for namespace of class which contains extension method declaration.

Lanorkin
  • 7,310
  • 2
  • 42
  • 60
1

As you have noticed, you cannot create new operators in C#. .NET does expose compiler classes though, so you could roll-your-own compiler that replaces these values right before processing them.

The extension method solution Lanorkin shared probably is the best if you want to keep conforming to C#. Another "solution" would be a namespace-less static Not class:

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);

For your new hires this would also clearly show that the operator is a new one, not a C# one.

Does your entire team feel that the exclamation mark hurts readability? Do they all have a good old c++ background? How big are your if statements? Have you considered swapping the if and else parts to reduce the need for notting in the first place?

If I would start to work for your company it would take me months to unlearn the exclamation mark.

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
  • Thank you for your answer. We dont have c++ Background, but from our point of view, C#'s !-Operator isnt as readable as the SQL equivalent NOT. Even && and || are making problems in some specific cases. You're correct, in some situations, we might be able to refactor those ifs and return.. For the rest of the Statements I guess we will have to stick to the !-Operator.. – Jannik Aug 14 '14 at 12:28
0

I sounds to me, after some clarification in comments, that you are on the wrong way.

Please don't try to make a function for trivial operations like !. This will not only clutter your code with something a new person doesn't understand, it will also cost you performance if the method isn't inlined.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

Extension methods are a good way to do this:

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

So regardless of where you are in the code you can call someBool.NOT();

If you absolutely want to only be able to call it as NOT(someBool) then do it like this:

public static class Extensions
{
    public static bool NOT(this object ignored, bool flag)
    {
        return !flag;
    }
}
Radu Porumb
  • 785
  • 5
  • 7