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

Как переопределить имена стандартных ключевых слов в С#

У меня есть интересная идея. Я хочу переопределить ключевые слова в С#, например заменить ключевое слово if на MyIf или что-то еще. Кто-нибудь имеет представление о том, как это сделать?

Как я думаю, он должен выглядеть примерно так:

namespace
{
   #define MyIf = if;
   #define MyElse = else;
   ...

   public someclass
   {
        public void someMethod()
        {
            MyIf(true)
            {
               ...
            }
            MyElse
            {
               ...
            }
        }
   }
}

Добавлено:

Возможно, существует способ создания библиотеки С++ или C, которая переопределит часть стандартного ядра С#?

** Примечание. Я знаю, что это плохая практика программирования, и я прошу всех программистов не использовать ответ в вашем корпоративном коде. **

4b9b3361

Ответ 1

Это невозможно: у С# нет препроцессора, такого как C и С++, поэтому нет механизма для преобразования источника, прежде чем компилятор увидит его. И, конечно же, компилятор распознает только стандартный if, поэтому нет и другой опции, которая каким-то образом преобразует источник, прежде чем компилятор увидит его.

Даже если бы это было возможно, это было бы всего лишь шагом ниже Ктулху в шкале ужасов.

Ответ 2

В С# вы можете переопределить перегружаемые операторы (+, -, ==) здесь: http://msdn.microsoft.com/en-us/library/8edha89s(v=vs.80).aspx

Но вы не можете действительно переопределять условные операторы.

То же самое относится к этим операторам: =,.,?:, → , new, is, sizeof, typeof, они не могут быть перегружены.

С# не поддерживает макросы, но, конечно же, вы можете написать собственный парсер, который обрабатывает макросы, прежде чем отправлять код в компилятор С#, посмотрите на Microsoft Roslyn.

http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx

Ответ 3

Вы можете использовать Монады с extension methods, например...

это Монада Возможно

    public static TInput If<TInput>(this TInput o, Predicate<TInput> evaluator)
        where TInput : class
    {
        if (o == null) return null;
        return evaluator(o) ? o : null;
    }

        public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator, TResult failureValue)
            where TInput : class
        {
            if (o == null) return failureValue;

            return evaluator(o);
        }

//использование

var result = ListOfObjects.If(o => o.Id == 1).Return(x => x.Object, null);

Ответ 4

Вы не можете переопределить if или else, потому что у С# нет препроцессора, который позволит вам сделать что-то подобное (возможно, также и для того, чтобы кто-то не мог так поступать).

Но вы можете переопределить, когда экземпляры ваших классов оцениваются до true/false (это самое близкое, которое вы можете получить):

public static bool operator true(YourType x)
{
    return x.IsLying ? !x.Whatever : x.Whatever;
}

public static bool operator false(YourType x)
{
    return x.IsLying ? x.Whatever : !x.Whatever;
}

Пример:

YourType wah = new YourType() { IsLying = true, Whatever = true };
if (wah) {
    // ...
}
else {
    // ...
}

Подробнее см. здесь:
http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx

Ответ 5

С# # define

#define позволяет вам определить символ, так что, используя символ в качестве выражения, переданного директиве #if, выражение будет оцениваться как true.

С# не имеет препроцессора , но имеет одинаковые директивы:

Хотя у компилятора нет отдельного препроцессора, директивы, описанные в этом разделе, обрабатываются так, как если бы они были. Они используются, чтобы помочь в условной компиляции. В отличие от директив C и С++, вы не можете использовать эти директивы для создания макросов.

Так что это не то же самое #define, что и в С++ или C. С# #define только заявляет, что существует литерал, но для этого литерала нет замены или макроса.

#define STRING int // Valid in C++ but invalid in C#

С++ # define

Директива #define заменяет токен-строку для всех последующих вхождений идентификатора в исходный файл. Идентификатор заменяется только тогда, когда он формирует токен. (См. Токены С++ в справочнике по языку С++.) Например, идентификатор не заменяется, если он появляется в комментарии, внутри строки или как часть более длинного идентификатора.

Ответ 6

В С# директивы препроцессора существуют для условно-компилируемого кода.

Например:

#define позволяет определить символ. Когда вы используете символ в качестве выражения, которое передается директиве #if, выражение будет оцените значение true.

Ответ 7

Сделайте что-то похожее на то, что вы хотите, вы можете переопределить неявный оператор bool:

using System;

class PleaseDontDoThis {
    public static implicit operator bool(PleaseDontDoThis h) {
        return (new Random().Next() % 2 == 0);
    }
}

static class Program {
    static void Main(string[] args) {
        var x = new PleaseDontDoThis();
        if (x) {
            Console.WriteLine("true");
        } else {
            Console.WriteLine("false");
        }
    }
}