Как вы можете видеть в приведенном ниже коде, я объявил Action<>
объект как переменную.
Кто-нибудь, пожалуйста, дайте мне знать, почему этот делегат метода действия ведет себя как статический метод?
Почему он возвращается true
в следующем коде?
Код:
public static void Main(string[] args)
{
Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };
Console.WriteLine(actionMethod.Method.IsStatic);
Console.Read();
}
Вывод:
c#
.net
reflection
lambda
Нуну
источник
источник
static
методов.Ildasm
действительно полезен для понимания того, что на самом деле происходит, я обычно используюIL
вкладкуLINQPad
для изучения небольших выборок.IL
вкладкуLINQPad
и вывел C #. Некоторые параметры для получения фактического эквивалента C # скомпилированного вывода могут заключаться в использованииILSpy
илиReflector
на скомпилированной сборке, вам, скорее всего, потребуется отключить некоторые параметры, которые будут пытаться отображать лямбды, а не классы, созданные компилятором.«Метод действия» статичен только как побочный эффект реализации. Это случай анонимного метода без захваченных переменных. Поскольку фиксированные переменные отсутствуют, у метода нет дополнительных требований к сроку службы, кроме общих требований к локальным переменным. Если он ссылался на другие локальные переменные, его время жизни расширяется до времени жизни этих других переменных (см. Раздел L.1.7, Локальные переменные и раздел N.15.5.1, Захваченные внешние переменные , в спецификации C # 5.0).
Обратите внимание, что спецификация C # говорит только об анонимных методах, преобразуемых в «деревья выражений», а не в «анонимные классы». Хотя дерево выражений может быть представлено как дополнительные классы C #, например, в компиляторе Microsoft, эта реализация не требуется (как указано в разделе M.5.3 в спецификации C # 5.0). Следовательно, не определено, является ли анонимная функция статической или нет. Более того, в разделе K.6 многое остается открытым в отношении деталей деревьев выражений.
источник
В Roslyn изменено поведение кэширования делегатов. Ранее, как указывалось, любое лямбда-выражение, которое не фиксировало переменные, компилировалось в
static
метод на сайте вызова. Рослин изменила это поведение. Теперь любая лямбда, которая захватывает переменные или нет, преобразуется в класс отображения:Учитывая этот пример:
Собственный вывод компилятора:
Рослин:
Изменения в поведении кэширования делегатов в Roslyn объясняют, почему это изменение было внесено.
источник
Начиная с C # 6, это всегда будет по умолчанию для методов экземпляра и никогда не будет статическим (поэтому
actionMethod.Method.IsStatic
всегда будет ложным).См. Здесь: Почему лямбда без захвата изменилась со статической в C # 5 на метод экземпляра в C # 6?
и здесь: Разница в оценке статического лямбда-выражения компилятора CSC и Roslyn?
источник
Этот метод не имеет закрытий, а также ссылается на сам статический метод (Console.WriteLine), поэтому я ожидал, что он будет статическим. Метод объявит закрывающий анонимный тип для закрытия, но в данном случае это не требуется.
источник