2011-09-03 5 views
19

Come può esistere la funzione globale in C# quando tutto è definito all'interno di una classe? Ero lettura della documentazione di OpCodes.Call a MSDN, e stato sorpreso vedere i seguenti diciture,Come può esistere la funzione globale in C#?

Il token metadati trasporta informazioni sufficienti per determinare se la chiamata è un metodo statico, un metodo di esempio, un metodo virtuale, o una funzione globale.

Funzione globale? Esiste in C#? (Sicuramente non si riferisce al metodo static, poiché è esplicitamente elencato insieme alla funzione globale).

+3

OpCodes.Call non è specifico per C#, ma per il CLR –

+0

Se vi dicessimo che avremmo dovuto kil tu. ;) Seriamente, i globals sono cattivi - non cercare di implementarli. – TrueWill

+0

Perché le funzioni/metodi globali sono cattivi per definizione? –

risposta

15

Non è possibile avere funzioni globali in C#, non fa parte del linguaggio. Devi utilizzare un metodo statico su alcune classi di tua scelta per ottenere funzionalità simili.

Tuttavia C# non è l'unica lingua che utilizza il CLR. Si può scrivere Managed C++, che può avere funzioni globali.

+1

Ma ho sentito e letto da qualche parte che quando si scrive Managed C++ (o C++/CLI), tutte le funzioni globali vengono inserite in una classe statica, generata dal compilatore. In effetti, non vi è alcuna nozione di funzioni globali. – Nawaz

+0

Questo può accadere sotto le coperte, non sono sicuro. Se trovi il link, per favore pubblicalo. Ci sono ancora altre lingue ... Non ho preso un sondaggio completo. –

+7

@Nawaz: Questo è un dettaglio di implementazione che non è pertinente a questa discussione. Il punto saliente di quel punto è che 'System.Reflection.Emit' appartiene a IL, non a C# o Managed C++ o qualsiasi altro linguaggio che è compilato in IL e si trova in cima a .NET Framework. Non importa se ci sono o non ci sono funzioni globali in Managed C++, o come sono implementate. Ciò che conta, è che in macchine virtuali o reali che interpretano IL, esiste una nozione di funzioni globali e 'System.Reflection.Emit.OpCodes.Call' può essere usato per emettere un codice operativo IL che può richiamare una funzione globale. – jason

3

Suppongo che il problema sia che questa operazione di iniezione è IL, ma IL è non assolutamente solo su C#. In altre parole è per il supporto del linguaggio che supporta le funzioni globali.

+0

Ad esempio? ... – Nawaz

+1

@Nawaz: Credo che si tratti di lingue dinamiche come, ad esempio IronPython, F # (non molto sicuro).Un materiale interessante può essere trovato qui sulla generazione dinamica del metodo: http://msdn.microsoft.com/en-us/library/system.reflection.emit.modulebuilder.createglobalfunctions(VS.95).aspx – Tigran

3

La documentazione a cui si riferisce è per .net. C# non soddisfa le funzioni globali ma .net lo fa.

+1

In che modo esattamente? Per favore sii più generoso nella tua risposta. :-) (Sono nuovo di .Net). – Nawaz

+2

.net è una piattaforma. Il compilatore C# esiste sopra quella piattaforma, ma .net è stato progettato per servire più di C#. I progettisti di C# hanno scelto di non occuparsi di funzioni globali nella progettazione di quella lingua, ma altri linguaggi creati su .net potevano scegliere di farlo. Infatti .net è pieno di funzionalità che non sono esposte attraverso le singole lingue. –

7

Perché System.Reflection.Emit.OpCodes.Call non riguarda C#. Si tratta di emettere i codici operativi IL. In IL, ci sono funzionalità che non sono disponibili in C#. Le funzioni globali sono una di quelle funzionalità.

3

C# non supporta tutte le funzionalità di MSIL. Le funzioni globali sono una di queste. VB.Net, F #, IronPython o qualche altro linguaggio preferiscono utilizzare questa e altre funzionalità che non sono generate dal compilatore C#.

+0

Potrebbero, potrebbero non farlo. Non importa. Il punto chiave è che IL li supporta e quindi macchine virtuali o reali che interpretano IL li supportano. Non importa se altri linguaggi sono compilati in IL, o se i compilatori di quelle lingue traducono tali funzioni globali in funzioni globali nell'IL compilato. – jason

3

Sto solo sovrascrivendo la mia risposta precedente ...

Ecco ciò che ogni sembrano in IL DASM con i relativi codici associati:

// 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() 

Quindi, per rispondere alla tua domanda, non c'è un modo diretto per generare il token di metadati nell'ultimo metodo per C#. Ho dovuto creare l'ultimo in C++.

11

Alla conferenza Build 2014 è stato annunciato che da Roslyn in poi, è possibile importare i metodi statici di tipi dalla direttiva using TypeName;, in modo che invece di dover utilizzare System.Math.Min(...) si può fare:

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

Nota: dal momento del rilascio questo è diventato:

using static System.Math; 
+0

+1. Grandi informazioni! – Nawaz

+0

Sebbene nel senso della domanda originale, questa non è ancora una funzione globale; è una sintassi sintattica che ti evita di digitare "System.Math.Min" o "Math.Min". Per quanto riguarda il runtime è ancora solo una funzione statica sulla classe "System.Math" – jimmyfever