17

I'm reading about extension methods, and monkeying around with them to see how they work, and I tried this:

namespace clunk {
    public static class oog {
        public static int doubleMe(this int x) {
            return 2 * x;
        }
    }

    class Program {
        static void Main() {
            Console.WriteLine(5.doubleMe());
        }
    }
}

and it worked as expected, successfully extending int with the doubleMe method, printing 10.

Next, being an old C guy, I wondered if I could do this:

namespace clunk {
    public static class BoolLikeC {
        public static bool operator true(this int i)  { return i != 0; }
        public static bool operator false(this int i) { return i == 0; }
    }

    class Program {
        static void Main() {
            if ( 7 ) {
                Console.WriteLine("7 is so true");
            }
        }
    }
}

I would think if the former would work, then the latter ought to work to make it such that an int used in a boolean context would call the extension method on int, check to see that 7 is not equal to 0, and return true. But instead, the compiler doesn't even like the later code, and puts the red squiggly lines under the two this's and says "Type expected". Why shouldn't this work?

IAbstract
  • 19,551
  • 15
  • 98
  • 146
Dave
  • 171
  • 1
  • 1
  • 3
  • Complete guess but, have you tried using the implicit keywork on the operators? – Andy Lowry Jul 11 '11 at 21:47
  • 1
    Well, that's not going to compile because you can't use extension methods to create overloaded operators. You could *maybe* create a `BoolLikeC` class that would work, but I'll argue that doing so is not a good idea. If you want to write C, then write C. There are very good reasons why C# was designed to make that kind of thing illegal. If you want to determine if an integer is 0 or not, then use the relevant language construct. – Jim Mischel Jul 11 '11 at 21:48
  • See http://stackoverflow.com/questions/172658/operator-overloading-with-c-extension-methods – Jim Mischel Jul 11 '11 at 21:49

7 Answers7

19

Very clever! A nice attempt, but regrettably we did not implement "extension everything", just extension methods.

We considered implementing extension properties, extension operators, extension events, extension constructors, extension interfaces, you name it, but most of them were not compelling enough to make it into C# 4 or the upcoming version of C#. We got as far as designing a syntax for the sort of thing you mention. We got rather farther on extension properties; we almost got extension properties into C# 4 but it ended up not working out. The sad story is here.

http://blogs.msdn.com/b/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx

So, long story short, no such feature, but we'll consider it for hypothetical future releases of the language.

You can of course make a "ToBool()" extension method on int if you really do like the retro C convention that non-zero-means-true.

shA.t
  • 16,580
  • 5
  • 54
  • 111
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 6
    Seeing the example in the question makes me cringe whenever I think of bool extension operators now... – BoltClock Jul 11 '11 at 22:07
14

Extension methods are exactly that—methods.
You cannot make extension operators or properties.

Had that been possible, it would result in very hard-to-read code.
If you aren't familiar with the code base, it's almost impossible to figure out what if (7) means.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
6

As others have said, there's no such thing as extension operators in C#.

The closest you can get, running the risk of facilitating lots of nasty bugs down the line, would be with implicit conversion operators on a custom "bridge" type:

// this works
BoolLikeC evil = 7;
if (evil) Console.WriteLine("7 is so true");

// and this works too
if ((BoolLikeC)7) Console.WriteLine("7 is so true");

// but this still won't work, thankfully
if (7) Console.WriteLine("7 is so true");

// and neither will this
if ((bool)7) Console.WriteLine("7 is so true");

// ...

public struct BoolLikeC
{
    private readonly int _value;
    public int Value { get { return _value; } }

    public BoolLikeC(int value)
    {
        _value = value;
    }

    public static implicit operator bool(BoolLikeC x)
    {
        return (x.Value != 0);
    }

    public static implicit operator BoolLikeC(int x)
    {
        return new BoolLikeC(x);
    }
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
2

Unfortunately you cannot introduce new operators, or implement support for existing operators, on types, through extension methods.

Basically, what you want to do cannot be done.

The only way to introduce new operators is to put them in one of the involved types. For binary operators you can put them in your own type, provided your type is one of the two, for unary types you need to put the operator inside the type itself.

Since you can't extend an int in any way, you can't do it.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

Console.WriteLine(5.doubleMe());

is equivalent to

Console.WriteLine(oog.doubleMe(5));

Given that, you can see why if ( 7 ) doesn't work.

Extension methods are nothing more than syntax.

As a side note since it is syntax you can call extension methods on null variables because it translates to a normal method call, and methods can take null parameters.

Davy8
  • 30,868
  • 25
  • 115
  • 173
1

Unfortunately you cannot use extension methods to add operators, and implicit type conversion in C# is implemented as an operator.

jbondeson
  • 111
  • 2
0

In the first instance you are writing an extension method - e.g. extending the functionality of the int data type. In the second code set, you are trying to override the bool operators. These are two totally different things.

IAbstract
  • 19,551
  • 15
  • 98
  • 146