Подтвердить что ты не робот

Использование методов расширения на int

Я читаю о методах расширения и обезьяне с ними чтобы посмотреть, как они работают, и я пробовал это:

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

и он работал, как ожидалось, успешно расширяя int с помощью метода doubleMe, печатая 10.

Затем, будучи старым парнем C, я подумал, могу ли я сделать это:

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

Я бы подумал, что если бы кто-то работал, то последний должен был сделать так, чтобы int, используемый в булевом контексте, вызовет метод расширения для int, проверьте, чтобы 7 не равно 0 и возвращает true. Но вместо этого компилятор даже не любит более поздний код, и ставит красные квадратики под двумя этими словами и говорит "Тип ожидается". Почему это не должно работать?

4b9b3361

Ответ 1

Очень умно! Хорошая попытка, но, к сожалению, мы не реализовали "расширение всего", просто методы расширения.

Мы рассмотрели возможность реализации свойств расширения, операторов расширений, событий расширения, конструкторов расширений, интерфейсов расширений, которые вы называете, но большинство из них не были достаточно убедительными, чтобы превратить их в С# 4 или предстоящую версию С#. Мы разработали синтаксис такого типа, о котором вы говорите. Мы довольно подробно относимся к свойствам расширения; мы почти получили свойства расширения в С# 4, но это не получилось. Печальная история здесь.

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

Итак, длинный рассказ, никакой такой функции, но мы рассмотрим его для гипотетических будущих выпусков языка.

Вы можете, конечно, сделать метод расширения ToBool() на int, если вам действительно нравится ретро-соглашение, что ненулевое значение означает true.

Ответ 2

Методы расширения - это именно те методы. Вы не можете создавать операторы расширения или свойства.

Если бы это было возможно, это привело бы к очень трудно читаемому коду.
Если вы не знакомы с базой кода, почти невозможно определить, что означает if (7).

Ответ 3

Как говорили другие, в С# нет таких операторов расширения.

Ближе всего вы можете получить, рискуя облегчить множество неприятных ошибок в строке, будут с неявными операциями преобразования на пользовательском "мостовом" типе:

// 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

К сожалению, вы не можете вводить новые операторы или реализовывать поддержку существующих операторов по типам с помощью методов расширения.

В принципе, то, что вы хотите сделать, не может быть выполнено.

Единственный способ введения новых операторов - разместить их в одном из задействованных типов. Для двоичных операторов вы можете поместить их в свой собственный тип, если ваш тип является одним из двух, для унарных типов вам нужно поставить оператор внутри самого типа.

Поскольку вы не можете расширить int каким-либо образом, вы не сможете этого сделать.

Ответ 5

Console.WriteLine(5.doubleMe());

эквивалентно

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

Учитывая это, вы можете понять, почему if ( 7 ) не работает.

Методы расширения - это не что иное, как синтаксис.

В качестве побочного примечания, поскольку это синтаксис, вы можете вызывать методы расширения для переменных null, потому что он переводит на обычный вызов метода, а методы могут принимать нулевые параметры.

Ответ 6

К сожалению, вы не можете использовать методы расширения для добавления операторов, а неявное преобразование типов в С# реализовано как оператор.

Ответ 7

В первом случае вы пишете метод расширения - например, расширяя функциональность типа данных int. Во втором наборе кода вы пытаетесь переопределить операторы bool. Это две совершенно разные вещи.