Что можно сделать в MSIL, который Вы не можете сделать в C# или VB.NET? [закрытый]

Это может быть похоже, вы можете попробовать это. Если не работает, пожалуйста, поделитесь своим файлом Gradle.

Ошибка: (30, 0) Не удалось найти метод compile () для аргументов

161
задан 35 revs, 6 users 61% 15 November 2015 в 18:10
поделиться

16 ответов

Я думаю тот, которого я продолжал желать (с полностью неправильными причинами), было наследование в Перечислениях. Это не походит на твердую вещь сделать в SMIL (так как Перечисления являются просто классами), но это не что-то, что синтаксис C# хочет, чтобы Вы сделали.

4
ответ дан Shalom Craimer 23 November 2019 в 21:27
поделиться

MSIL допускает перегрузки, которые отличаются только в ответ типы из-за

call void [mscorlib]System.Console::Write(string)

или

callvirt int32 ...
34
ответ дан Anton Gogolev 23 November 2019 в 21:27
поделиться

Native types
можно работать с собственными международными и собственными неподписанными международными типами непосредственно (в c#, можно только работать над IntPtr, который не является тем же.

Transient Pointers
можно играть с переходными указателями, которые являются указателями на управляемые типы, но гарантируемый не переместиться в память, так как они не находятся в управляемой "куче". Не совсем уверенный, как Вы могли полезно использовать это, не смешивая с неуправляемым кодом, но он не представлен другим языкам непосредственно только через вещи как stackalloc.

<Module>
можно иметь предосудительные отношения с классом если Вы, так требуйте (можно сделать это отражением, не нуждаясь в IL)

.emitbyte

15.4.1.1 .emitbyte направляющий MethodBodyItem:: = †¦ | .emitbyte Int32 Эта директива заставляет неподписанное 8-разрядное значение испускаться непосредственно в поток CIL метода в точке, в которой появляется директива. [Отметьте: .emitbyte директива используется для генерации тестов. Это не требуется в генерации обычных программ. закончите примечание]

.entrypoint
, у Вас есть немного больше гибкости на этом, можно применить его к методам, не названным Основными, например.

имеют чтение спецификация , я уверен, что Вы найдете еще много.

7
ответ дан ShuggyCoUk 23 November 2019 в 21:27
поделиться

IL имеет различие между call и callvirt для виртуальных вызовов метода. При помощи первого можно вызвать вызов виртуального метода текущий статический тип класса вместо виртуальной функции в динамическом типе класса.

C# не имеет никакого способа сделать это:

abstract class Foo {
    public void F() {
        Console.WriteLine(ToString()); // Always a virtual call!
    }

    public override string ToString() { System.Diagnostics.Debug.Assert(false); }
};

sealed class Bar : Foo {
    public override string ToString() { return "I'm called!"; }
}

VB, как IL, может издать невиртуальные приказы при помощи MyClass.Method() синтаксис. В вышеупомянутом это было бы MyClass.ToString().

10
ответ дан Konrad Rudolph 23 November 2019 в 21:27
поделиться

В IL можно бросить и поймать любой тип вообще, не просто вводит полученный от System.Exception.

14
ответ дан Daniel Earwicker 23 November 2019 в 21:27
поделиться

CLR уже поддерживает универсальный co/contravariance, но C# не получает эту функцию до 4.0

17
ответ дан ermau 23 November 2019 в 21:27
поделиться

Ох, я не определил это в то время. (Если Вы добавляете тег jon-стрельбы-по-тарелочкам, это более вероятно, но я не проверяю его настолько часто.)

похоже, что у Вас уже есть довольно хорошие ответы. Кроме того:

  • Вы не можете разобраться с помещенной в коробку версией типа значения в C#. Вы можете в C++ / CLI
  • , Вы не можете сделать попытки/отказа в C# ("отказ" является подобным "выгода все и перебросок в конце блока" или "наконец, но только при отказе")
  • существует много имен, которые запрещаются C#, но легальный IL
  • IL позволяет, Вы к определяете своих собственных конструкторов без параметров для типов .
  • значения
  • , Вы не можете определить события с элементом "повышения" в C#. (В VB Вы имеете к для пользовательских событий, но события "по умолчанию" не включают тот.)
  • Некоторые преобразования позволяются CLR, но не C#. Если Вы пойдете через object в C#, то они будут иногда работать. Посмотрите uint [] / интервал [] ТАК вопрос для примера.

я добавлю к этому, если я буду думать о чем-либо еще...

18
ответ дан 4 revs, 2 users 93% 23 November 2019 в 21:27
поделиться

В MSIL у Вас может быть класс, который не может наследоваться Системе. Объект.

Пример кода: скомпилируйте его с ilasm.exe ОБНОВЛЕНИЕ: необходимо использовать "/NOAUTOINHERIT" для предотвращения ассемблера от автоматического наследования.

// Metadata version: v2.0.50215
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly sample
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module sample.exe
// MVID: {A224F460-A049-4A03-9E71-80A36DBBBCD3}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x02F20000


// =============== CLASS MEMBERS DECLARATION ===================

.class public auto ansi beforefieldinit Hello
{
  .method public hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // Code size       13 (0xd)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World!"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  ret
  } // end of method Hello::Main
} // end of class Hello
21
ответ дан Ramesh 23 November 2019 в 21:27
поделиться

Возможно объединиться protected и internal модификаторы доступа. В C#, если Вы пишете protected internal, участник доступен от блока и от производных классов. Через MSIL можно получить участника, который доступен от производных классов в рамках блока только . (Я думаю, что это могло быть довольно полезно!)

20
ответ дан yatima2975 23 November 2019 в 21:27
поделиться

Большинство языков .NET включая C# и VB не использует функцию хвостовой рекурсии кода MSIL.

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

код MSIL поддерживает хвостовую рекурсию явно, и для некоторых алгоритмов это могло быть важной оптимизацией для создания. Но так как C# и VB не генерируют инструкции сделать это, он должен быть сделан вручную (или использующий F# или некоторый другой язык).

Вот пример того, как хвостовая рекурсия может быть реализована вручную в C#:

private static int RecursiveMethod(int myParameter)
{
    // Body of recursive method
    if (BaseCase(details))
        return result;
    // ...

    return RecursiveMethod(modifiedParameter);
}

// Is transformed into:

private static int RecursiveMethod(int myParameter)
{
    while (true)
    {
        // Body of recursive method
        if (BaseCase(details))
            return result;
        // ...

        myParameter = modifiedParameter;
    }
}

Это - обычная практика для удаления рекурсии путем перемещения локальных данных из аппаратной стопки на выделенную "куче" структуру данных стека. В устранении рекурсии последнего вызова как показано выше, стек устраняется полностью, который является довольно хорошей оптимизацией. Кроме того, возвращаемое значение не должно идти по долгой цепочке вызовов, но оно возвращается непосредственно.

, Но, так или иначе, CIL обеспечивает эту функцию как часть языка, но с C# или VB это должно быть реализовано вручную. (Дрожание также свободно сделать эту оптимизацию самостоятельно, но это - целая другая проблема.)

28
ответ дан Jeffrey L Whitledge 23 November 2019 в 21:27
поделиться

С IL и VB.NET можно добавить фильтры при ловле исключений, но C# v3 не поддерживает эту функцию.

Этот пример VB.NET взят от http://blogs.msdn.com/clrteam/archive/2009/02/05/catch-rethrow-and-filters-why-you-should-care.aspx (отметьте When ShouldCatch(ex) = True в пункте Выгоды):

Try
   Foo()
Catch ex As CustomBaseException When ShouldCatch(ex)
   Console.WriteLine("Caught exception!")
End Try
9
ответ дан Ry- 23 November 2019 в 21:27
поделиться

Вот еще кое-что:

  1. Вы можете иметь дополнительные методы экземпляра в делегатах.
  2. Делегаты могут реализовывать интерфейсы.
  3. Вы можете иметь статические члены в делегатах и ​​интерфейсах.
4
ответ дан 23 November 2019 в 21:27
поделиться

20) Вы можете рассматривать массив байтов как (в 4 раза меньший) массив целых чисел.

Я недавно использовал это для быстрой реализации XOR, так как функция CLR xor работает с ints, и мне нужно было выполнить XOR в потоке байтов.

Полученный код оказался примерно в 10 раз быстрее, чем эквивалент, выполненный на C # (выполнение XOR для каждого байта).

===

Я не делаю ' У меня достаточно stackoverflow street credz, чтобы отредактировать вопрос и добавить его в список как # 20, если бы кто-то другой мог это было бы здорово; -)

3
ответ дан 23 November 2019 в 21:27
поделиться

Насколько мне известно, нет возможности создавать инициализаторы модулей (статические конструкторы для всего модуля) непосредственно в C #:

http://blogs.msdn.com/junfeng/ archive / 2005/11/19 / 494914.aspx

8
ответ дан 23 November 2019 в 21:27
поделиться

Что-то, что используют обфускаторы - у вас может быть одно и то же имя для поля / метода / свойства / события.

3
ответ дан 23 November 2019 в 21:27
поделиться

Вы можете взломать метод, переопределив co / counter-variance, который C # не допускает (это НЕ то же самое, что общая дисперсия!) . У меня есть дополнительная информация о реализации этого здесь , а части 1 и 2

6
ответ дан 23 November 2019 в 21:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: