Как переопределить имена стандартных ключевых слов в С#
У меня есть интересная идея. Я хочу переопределить ключевые слова в С#, например заменить ключевое слово if
на MyIf
или что-то еще. Кто-нибудь имеет представление о том, как это сделать?
Как я думаю, он должен выглядеть примерно так:
namespace
{
#define MyIf = if;
#define MyElse = else;
...
public someclass
{
public void someMethod()
{
MyIf(true)
{
...
}
MyElse
{
...
}
}
}
}
Добавлено:
Возможно, существует способ создания библиотеки С++ или C, которая переопределит часть стандартного ядра С#?
** Примечание. Я знаю, что это плохая практика программирования, и я прошу всех программистов не использовать ответ в вашем корпоративном коде. **
Ответы
Ответ 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 позволяет вам определить символ, так что, используя символ в качестве выражения, переданного директиве #if, выражение будет оцениваться как true.
С# не имеет препроцессора , но имеет одинаковые директивы:
Хотя у компилятора нет отдельного препроцессора, директивы, описанные в этом разделе, обрабатываются так, как если бы они были. Они используются, чтобы помочь в условной компиляции. В отличие от директив C и С++, вы не можете использовать эти директивы для создания макросов.
Так что это не то же самое #define, что и в С++ или C. С# #define только заявляет, что существует литерал, но для этого литерала нет замены или макроса.
#define STRING int // Valid in C++ but invalid in C#
Директива #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");
}
}
}