using extension methods on int

2019-04-04 08:22发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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


回答4:

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.



回答5:

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.



回答6:

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



回答7:

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.