Как глобальная функция может существовать в С#?

Как глобальная функция может существовать в C#, когда все определено внутри класса? Я читал документацию по OpCodes.Call в MSDN, и был удивлен, увидев следующие формулировки,

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

Глобальная функция? Существует ли он в C#? (Это определенно не относится к методу static, так как он явно указан вместе с глобальной функцией).


person Nawaz    schedule 03.09.2011    source источник
comment
OpCodes.Call относится не только к C#, но и к среде CLR.   -  person Rune FS    schedule 04.09.2011
comment
Если бы мы сказали тебе, нам пришлось бы тебя убить. ;) Серьезно, глобалы плохи - не стремитесь их реализовать.   -  person TrueWill    schedule 04.09.2011
comment
Почему глобальные функции/методы плохи по определению?   -  person Dennis Smit    schedule 04.09.2011
comment
@Dennis stackoverflow.com/questions /3151768/   -  person Paul Walls    schedule 04.09.2011


Ответы (7)


У вас не может быть глобальных функций в C#, это просто не часть языка. Вы должны использовать статический метод для некоторого класса по вашему выбору, чтобы получить аналогичную функциональность.

Однако C# — не единственный язык, использующий CLR. Можно написать Managed C++, который может иметь глобальные функции.

person i_am_jorf    schedule 03.09.2011
comment
Но я где-то слышал и читал, что когда вы пишете Managed C++ (или C++/CLI), все глобальные функции помещаются в статический класс, сгенерированный компилятором. По сути, понятия глобальных функций не существует. - person Nawaz; 04.09.2011
comment
Это может произойти под одеялом, я не уверен. Если найдёте ссылку, киньте пожалуйста. Есть еще другие языки... Я не проводил полный опрос. - person i_am_jorf; 04.09.2011
comment
@Nawaz: Это деталь реализации, которая не имеет отношения к этому обсуждению. Важно отметить, что System.Reflection.Emit относится к IL, а не к C# или управляемому C++ или любому другому языку, который скомпилирован в IL и находится поверх .NET Framework. Неважно, есть или нет глобальные функции в Managed C++ или как они реализованы. Важно то, что в виртуальных или реальных машинах, которые интерпретируют IL, существует понятие глобальных функций, и System.Reflection.Emit.OpCodes.Call можно использовать для создания кода операции IL, который может вызывать глобальную функцию. - person jason; 04.09.2011

На конференции Build 2014 было объявлено, что, начиная с Roslyn, вы можете импортировать статические методы из типов с помощью директивы using TypeName;, так что вместо использования System.Math.Min(...) вы можете сделать:

using System.Math;
...
var z = Min(x,y);

Примечание: к моменту выпуска это стало:

using static System.Math;
person Marc Gravell    schedule 03.04.2014
comment
Хотя в смысле исходного вопроса это все же не глобальная функция; это синтаксическое сокращение, которое избавляет вас от ввода System.Math.Min или Math.Min. Что касается времени выполнения, это все еще просто статическая функция класса System.Math. - person jimmyfever; 26.02.2016

Потому что System.Reflection.Emit.OpCodes.Call не о C#. Речь идет об генерировании кодов операций IL. В IL есть функции, недоступные в C#. Глобальные функции — одна из таких функций.

person jason    schedule 03.09.2011

Я предполагаю, что дело в том, что это операция внедрения IL, но IL не абсолютно только про C#. Другими словами, это поддержка языка, поддерживающего глобальные функции.

person Tigran    schedule 03.09.2011
comment
@Nawaz: я считаю, что речь идет о динамических языках, таких как IronPython, F # (не очень уверен). Здесь можно найти интересный материал о динамическом создании методов: msdn.microsoft.com/en-us/library/ - person Tigran; 04.09.2011

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

person David Heffernan    schedule 03.09.2011
comment
Как именно? Пожалуйста, будьте более щедры в своем ответе. :-) (я новичок в .Net). - person Nawaz; 04.09.2011
comment
.net — это платформа. Компилятор C# существует поверх этой платформы, но .net был разработан не только для C#. Разработчики C# решили не учитывать глобальные функции при проектировании этого языка, но другие языки, построенные на .net, могли сделать это. На самом деле .net полон функций, которые не раскрываются через отдельные языки. - person David Heffernan; 04.09.2011

C# не поддерживает все функции MSIL. Глобальные функции — одна из них. VB.Net, F#, IronPython или какой-либо другой язык может использовать эту и другие функции, которые не генерируются компилятором C#.

person Alexei Levenkov    schedule 03.09.2011
comment
Могут, могут нет. Это не имеет значения. Ключевым моментом является то, что IL поддерживает их, и, следовательно, их поддерживают виртуальные или реальные машины, которые интерпретируют IL. Неважно, делают ли это другие языки, скомпилированные в IL, или компиляторы для этих языков переводят эти глобальные функции в глобальные функции в скомпилированном IL. - person jason; 04.09.2011

Я просто перезаписываю свой предыдущий ответ...

Вот как они выглядят в IL DASM с соответствующими кодами:

// Static Method
IL_0001:  call       void testapp.Form1::Test()

// Instance Method
IL_0001:  call       instance void testapp.Form1::Test()

// Virtual Method
IL_0001:  callvirt   instance void testapp.Form1::Test()

// Global Function
IL_0000:  call       void testapp.Test()

Итак, чтобы ответить на ваш вопрос, нет прямого способа создать токен метаданных в последнем методе для С#. Мне пришлось создать последний на C++.

person Paul Walls    schedule 04.09.2011