Ответ 1
Если вы действительно хотите noop, тогда это определяет безымянное действие, которое ничего не делает, а затем вызывает его, в результате чего ничего не происходит:
((Action)(() => { }))();
Что такое простая инструкция Noop в С#, которая не требует применения метода? (Однако методы Inline/Lambda в порядке.)
Мой текущий вариант использования: я хочу занять catch-блок try-catch, поэтому я могу войти в него во время отладки и проверки исключения.
Я знаю, что я, вероятно, должен обрабатывать/регистрировать исключение в любом случае, но это не точка этого упражнения.
Если вы действительно хотите noop, тогда это определяет безымянное действие, которое ничего не делает, а затем вызывает его, в результате чего ничего не происходит:
((Action)(() => { }))();
Стандартная операция пустой операции /noop в С# равна
;
как в:
if (true)
;
(соответствующая документация)
это конкретно касается вашего прецедента (просто поместите точку прерывания на строку или иначе на нее), минимально и напрямую поддерживается средой именно для этой цели (так что вы даже, если вы делая сложные вещи, например, глядя на скомпилированный источник, у вас не будет никакого дополнительного шума/и т.д., чтобы беспокоиться из компилятора/оптимизатора и т.д.) - и имеет дополнительное преимущество для предупреждения напоминание, чтобы очистить его от вашего кода, когда вы закончите отладку/нажмите на производство
Если вы хотите вломиться в метод, вы можете жестко определить точку останова:
System.Diagnostics.Debugger.Break();
В качестве альтернативы, если вы не компилируете в режиме деблокирования, следующая строка выдаст IL, который вы можете сломать:
var a = 1;
Вы также можете написать Debug.Break(), специфичный для вашей машины:
[Conditional("DEBUG")]
[Obsolete("Please remove me before checkin.")]
public static void Break()
{
#IF DEBUG
if (Dns.GetHostName() == "PROTECTORONE")
Debugger.Break();
#ENDIF
}
Обратите внимание, что из-за [Conditional("DEBUG")]
этот метод не будет вызван в узлах вызова во время сборки RELEASE.
Вы можете написать функцию, которая ничего не делает.
public static void Noop()
{
}
Вы можете просто написать:
catch {
;
}
Пустым оператором с одной точкой с запятой является С# NOOP.
Как насчет:
GC.KeepAlive(e);
где e
- переменная исключения?
(Я не пробовал помещать точку останова в самом объявлении catch. Похоже, вы должны это сделать именно по этой причине. Но работает ли это или нет, это другое дело.)
Или несколько более загадочно, предполагая, что у вас уже есть директива using для System.LINQ
:
"".AsEnumerable();
В дополнение к ответам, которые непосредственно отвечают на вопрос.
Если вы просто хотите сломать, вы всегда можете поставить точку останова на открытии {
или закрытии }
блока catch
.
Зачем переусердствовать?
var x = 0;
отлично работает:)
Стандартная операция пустой операции /noop в С# равна
;
, как вif (true) ;
.
- голубые поля
Но, используя этот стандарт ;
как ветвь оператора if
, заставляет MS Visual Studio 2010 показывать предупреждение: "Возможная ошибка пустой инструкции". (Предупреждение CS0642, хотя VS2010 не говорит мне об этом или не ссылается на фактическую помощь для предупреждения.)
Хуже того, Спецификация языка MSDN С# не упоминает, что на самом деле кодирование этой пустой инструкции как ветки оператора if
вызывает предупреждение CS0642 "Возможная ошибка пустой инструкции". (Предупреждение, потому что это "плохая форма", потенциально неоднозначная.)
Хуже того, похоже, что VS2010 не дает возможности БЕСПЛАТНО подавить индивидуальное предупреждение. Я должен был бы вставить #pragma warning disable CS0642
до строки (а) и [необязательно] #pragma warning disable CS0642
после. Для меня это уродливее, чем предупреждение. Я бы лучше использовал { }
вместо ;
. (Я могу использовать переопределение, которое немного менее уродливо.)
Я просмотрел здесь "С# no-op", потому что мне нужна была альтернатива "пустой инструкции", чтобы избавиться от этого предупреждения. Мне не нужен контрольный пункт. Я просто хочу сделать [абсолютно] - ничего, что не является двусмысленным, как "пустое утверждение".
Альтернатива не должна вызывать НЕКОТОРЫЕ ДРУГИЕ предупреждения. int u;
не годится, потому что он вызывает предупреждение. "Переменная" u "объявлена, но никогда не используется". int u = 0;
не является хорошим, потому что он вызывает предупреждение. "Переменная" u "назначается, но ее значение никогда не используется".
Если noop;
(или аналогичный) были добавлены как однозначный пустой оператор (НЕ определение макроса), это было бы здорово.
Если noop();
(или аналогичный) была функцией с пустым телом (которое может полностью исчезнуть, когда компилятор встраивает его), это будет почти отлично.
Когда ветка является только одним утверждением, я часто опускаю окружающие строки {
и }
, потому что они не нужны, и они растягивают код по вертикали, что затрудняет чтение. Непоследовательность в языке заключается в том, что я не могу опустить окружающие строки {
и }
, когда они окружают операторы ZERO. Я могу сжать две строки до { }
в одной строке, но это противоречиво. Я думаю, что ;
на линии - это самое опрятное решение, и оно НЕ должно вызывать предупреждение на [неустановленных] основаниях "плохой формы". Я думаю, что предупреждение CS0642 должно быть отключено. Я думаю, что следующий код должен быть приемлемым как есть:
if (condition1)
action1;
else if (condition2)
; // (do nothing)
else if (condition3)
action3;
else if (condition4)
; // (do nothing)
else if (condition5)
action5;
else
action99;
(Я жаловался, что не могу написать это как комментарий, потому что у меня еще не было 50 рецензий, чтобы комментировать ". Теперь, когда я могу прокомментировать, при 2 Кбайтах, это слишком длинный комментарий, равный 1,5 Кбайтам, поэтому он остается здесь.)
Ну, NOP в С# существует, как и в C, и является ';'
, и его правильное определение - это "пустой оператор", но для использования, которое вы намереваетесь, достаточно, чтобы поставить точку останова в конечную скобку catch...
Нет необходимости сохранять Alive anithing, так как время жизни ссылки на объект в методе расширяется до конца метода при подключении отладчика. Поэтому вам просто нужно написать
catch(Exception exception)
{
}
и установите точку останова на закрывающей скобке и просмотрите содержимое исключений.
Я знаю, что это старый вопрос, и, технически, этот ответ не относится к варианту использования asker. Тем не менее, есть инструкция NOOP в CIL, которая является nop
. В качестве эксперимента возьмите следующее приложение CIL.
.assembly extern mscorlib {}
.assembly Test
{
.ver 1:0:1:0
}
.module test.exe
.method static void main() cil managed
{
.maxstack 1
.entrypoint
nop
nop
nop
nop
ret
}
Если вы компилируете приложение и декомпилируете его с помощью инструмента, подобного ILSpy, в С#, это содержимое метода main():
static void main()
{
}
Как видите, там ничего нет. Однако, если мы хотим убедиться, что компилятор CIL не оптимизировал эти операторы nop
, мы можем просмотреть наше приложение в декомпилированном коде IL в ILSpy, и это то, что мы видим для основного метода:
.method static privatescope
void main$PST06000001 () cil managed
{
// Method begins at RVA 0x2050
// Code size 5 (0x5)
.maxstack 1
.entrypoint
IL_0000: nop
IL_0001: nop
IL_0002: nop
IL_0003: nop
IL_0004: ret
} // end of method '<Module>'::main
CIL, безусловно, компилирует инструкции nop
в сборку. Поскольку в С# нет реализации этой инструкции, эти команды nop
не отображаются в разобранном коде С#.
У меня нет лицензии на Reflector, но я думаю, что если вы декомпилируете эти двоичные файлы с помощью Reflector, вы получите аналогичный вывод для С#.
Вы пытаетесь отладить выпуск (оптимизированную) сборку? Обычно оптимизатор удаляет незаписанные переменные и пустые блоки.
Два решения:
catch
и используйте $exception
- созданный отладчиком для ссылки на исключение в полете - в окне инструмента "Локали".Надежное решение
try
{
blablablablaStatemnt();
}
catch(Exception ex)
{
#IF DEBUG
Debugger.Break();
#END IF
}
Проще, чем это!
В противном случае
может быть очень полезным;
Это дополнение к ответу @AHM, так как я хотел простой способ сделать NOOP для целей отладки (связь с AB PLC CompactLogix и возникли ошибки, которые действительно видны только в разборке из-за импорта библиотеки библиотеки C++ в С#).
Я взял однострочник
((Action)(() => { }))();
и поместите его в фрагмент с именем noop.snippet, а затем поместите в папку с именем My Code Snippets.
(Инструменты → Диспетчер фрагментов кода → Местоположение) ИЛИ Аккорд (Ctrl + K, Ctrl + B)
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>noop</Title>
<Shortcut>noop</Shortcut>
<Description>Code snippet to inject an assembly (x86) equivalent of the NOOP command into the code disassembly.</Description>
<Author>Jay Whaley</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="csharp">
<![CDATA[// Forces a psuedo NOOP in disassembly
((Action)(() => { }))();
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
Это помогает быстро использовать ярлык на случай, если низкоуровневая связь становится запутанной, и требует, чтобы это была обычная тактика отладки. Фактическая сгенерированная сборка выглядит следующим образом, но есть несколько постов о том, как использовать фактическую сборку, встроенную в С#.
Мне это очень нравится, просто потому, что это смутит того, кто его встретит:
catch (SomeException e)
{
lock(e);
}