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

Простое выражение С# Noop

Что такое простая инструкция Noop в С#, которая не требует применения метода? (Однако методы Inline/Lambda в порядке.)

Мой текущий вариант использования: я хочу занять catch-блок try-catch, поэтому я могу войти в него во время отладки и проверки исключения.
Я знаю, что я, вероятно, должен обрабатывать/регистрировать исключение в любом случае, но это не точка этого упражнения.

4b9b3361

Ответ 1

Если вы действительно хотите noop, тогда это определяет безымянное действие, которое ничего не делает, а затем вызывает его, в результате чего ничего не происходит:

((Action)(() => { }))();

Ответ 2

Стандартная операция пустой операции /noop в С# равна

;

как в:

if (true)
    ;

(соответствующая документация)

это конкретно касается вашего прецедента (просто поместите точку прерывания на строку или иначе на нее), минимально и напрямую поддерживается средой именно для этой цели (так что вы даже, если вы делая сложные вещи, например, глядя на скомпилированный источник, у вас не будет никакого дополнительного шума/и т.д., чтобы беспокоиться из компилятора/оптимизатора и т.д.) - и имеет дополнительное преимущество для предупреждения напоминание, чтобы очистить его от вашего кода, когда вы закончите отладку/нажмите на производство

Ответ 3

Если вы хотите вломиться в метод, вы можете жестко определить точку останова:

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.

Ответ 4

Вы можете написать функцию, которая ничего не делает.

public static void Noop()
{
}

Ответ 5

Вы можете просто написать:

catch {
    ;
}

Пустым оператором с одной точкой с запятой является С# NOOP.

Ответ 6

Как насчет:

GC.KeepAlive(e);

где e - переменная исключения?

(Я не пробовал помещать точку останова в самом объявлении catch. Похоже, вы должны это сделать именно по этой причине. Но работает ли это или нет, это другое дело.)

Или несколько более загадочно, предполагая, что у вас уже есть директива using для System.LINQ:

"".AsEnumerable();

Ответ 7

В дополнение к ответам, которые непосредственно отвечают на вопрос.


Если вы просто хотите сломать, вы всегда можете поставить точку останова на открытии { или закрытии } блока catch.

Ответ 8

Зачем переусердствовать?

var x = 0;

отлично работает:)

Ответ 9

Стандартная операция пустой операции /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 Кбайтам, поэтому он остается здесь.)

Ответ 10

Ну, NOP в С# существует, как и в C, и является ';', и его правильное определение - это "пустой оператор", но для использования, которое вы намереваетесь, достаточно, чтобы поставить точку останова в конечную скобку catch... Нет необходимости сохранять Alive anithing, так как время жизни ссылки на объект в методе расширяется до конца метода при подключении отладчика. Поэтому вам просто нужно написать

catch(Exception exception)
{
}

и установите точку останова на закрывающей скобке и просмотрите содержимое исключений.

Ответ 11

Я знаю, что это старый вопрос, и, технически, этот ответ не относится к варианту использования 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, вы получите аналогичный вывод для С#.

Ответ 12

Вы пытаетесь отладить выпуск (оптимизированную) сборку? Обычно оптимизатор удаляет незаписанные переменные и пустые блоки.

Два решения:

  • Отладка в сборке отладки.
  • Поместите точку останова на catch и используйте $exception - созданный отладчиком для ссылки на исключение в полете - в окне инструмента "Локали".

Ответ 13

Надежное решение

try
{
   blablablablaStatemnt();
}
catch(Exception ex)
{
    #IF DEBUG
       Debugger.Break();
    #END IF
}

Проще, чем это!

В противном случае

точки останова

может быть очень полезным;

Ответ 14

Это дополнение к ответу @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>

Это помогает быстро использовать ярлык на случай, если низкоуровневая связь становится запутанной, и требует, чтобы это была обычная тактика отладки. Фактическая сгенерированная сборка выглядит следующим образом, но есть несколько постов о том, как использовать фактическую сборку, встроенную в С#.

Disassembly generated from invoking a nameless action

Ответ 15

Мне это очень нравится, просто потому, что это смутит того, кто его встретит:

catch (SomeException e)
{
    lock(e);
}