2012-06-16 8 views
11

Ho dovuto decompilare un codice e non so cosa sia questa sintassi? Puoi aiutarmi o indicarmi un articolo su cosa sia? Ho cercato su Google e cercato questo sito e non riesco a trovare nulla.Che cos'è il carattere di e commerciale alla fine di un tipo di oggetto?

una sola riga di codice:

Rectangle pageBounds; 
    // ISSUE: explicit reference operation 
    // ISSUE: variable of a reference type 
    Rectangle& local = @pageBounds; 

Qual è il simbolo "&" alla fine del tipo di oggetto Rectangle, e la "@" prima che la variabile pageBounds?

Questa è la mia ultima riga di codice che ho bisogno di correggere per ottenere nuovamente questo eseguibile da compilare.

Ecco il metodo che utilizza questa sintassi, posso farla franca rimuovendola?

protected override void OnPrintPage(PrintPageEventArgs e) 
{ 
    Application.DoEvents(); 
    ++this._pageNum; 
    float num1; 
    if (this.Header != null) 
    { 
    num1 = this.Header.CalculateHeight(this, e.Graphics); 
    this.Header.Draw(this, (float) e.MarginBounds.Top, e.Graphics, e.MarginBounds); 
    } 
    else 
    num1 = 0.0f; 
    float num2; 
    if (this.Footer != null) 
    { 
    num2 = this.Footer.CalculateHeight(this, e.Graphics); 
    this.Footer.Draw(this, (float) e.MarginBounds.Bottom - num2, e.Graphics, e.MarginBounds); 
    } 
    else 
    num2 = 0.0f; 
    Rectangle pageBounds; 
    // ISSUE: explicit reference operation 
    // ISSUE: variable of a reference type 
    Rectangle& local = @pageBounds; 
    int left = e.MarginBounds.Left; 
    Rectangle marginBounds = e.MarginBounds; 
    int y = (int) ((double) marginBounds.Top + (double) num1); 
    marginBounds = e.MarginBounds; 
    int width = marginBounds.Width; 
    marginBounds = e.MarginBounds; 
    int height = (int) ((double) marginBounds.Height - (double) num2 - (double) num1); 
    // ISSUE: explicit reference operation 
    local = new Rectangle(left, y, width, height); 
    float yPos = (float) pageBounds.Top; 
    bool flag = false; 
    int num3 = 0; 
    while (this._printIndex < this._printElements.Count) 
    { 
    PrintElement printElement = (PrintElement) this._printElements[this._printIndex]; 
    float num4 = printElement.CalculateHeight(this, e.Graphics); 
    if ((double) yPos + (double) num4 > (double) pageBounds.Bottom && num3 != 0) 
    { 
     flag = true; 
     break; 
    } 
    else 
    { 
     printElement.Draw(this, yPos, e.Graphics, pageBounds); 
     yPos += num4; 
     ++this._printIndex; 
     ++num3; 
    } 
    } 
    e.HasMorePages = flag; 
} 
+1

leggere su riferimenti e puntatori – Tschallacka

+0

@MichaelDibbets: Questo è C# ... – Ryan

+0

C# ha riferimenti, puntatori, * e * valore t ypes;) –

risposta

19

I commenti destra prima di quella linea di codice che dicono esattamente cosa sta succedendo. Il segno & dopo il nome di un tipo indica che si tratta di un tipo di riferimento e @ prima di un nome di variabile genera un riferimento a tale variabile.

(Il simbolo @ può essere utilizzato anche in codice C# per "fuga" parole chiave per l'uso come nomi di variabili, ma che non è quello che sta accadendo qui. "PageBounds" non è una C# parola chiave.)

Si noti che questo non è una sintassi C# valida - non puoi prendere un riferimento a una variabile locale in C#. Ciò accade implicitamente quando si utilizzano i parametri ref e out, ad esempio, ma le parole chiave vengono utilizzate invece di digitare esplicitamente i parametri come riferimento. (. Per esempio se si ha un out int x, internamente quella variabile è di tipo Int32&) Il intento del codice, se fosse legale C#, sarebbe che pageBounds e local erano le stessa istanza con due nomi diversi; tutto ciò che fai per uno accade all'altro. Così, per esempio, questo codice illegale:

Rectangle pageBounds; 
Rectangle& local = @pageBounds; 
local = new Rectangle(); 

sarebbe lo stesso di questo codice legale:

Rectangle pageBounds = new Rectangle(); 

Se si è tentato di compilare il codice in-decompilato, si otterrebbe un errore perché il il compilatore considera & come bit a bit e, e si lamenterà che hai usato un tipo come se fosse una variabile. Ma va bene perché non l'hai preso da un file sorgente C#. È stato decompilato un metodo IL per ottenerlo e ci sono molte cose che puoi fare in IL che sono illegali in C#. Questo accade sempre quando decompilate il codice; per esempio, vedi nomi di classi e metodi illegali.Significa solo che il compilatore ha generato IL in base al codice originale che non traduce direttamente in C#, ma si comporta come nel modo desiderato. Il codice che stai recuperando è il miglior tentativo del decompilatore di produrre codice C# dall'IL che ha.

Potete vedere esempi del tipo di codice che produce questi riferimenti nelle numerose segnalazioni di bug JetBrains su di loro:

+0

risposta fantastica. Grazie per la spiegazione, ora ha un senso. Per la mia situazione, è facile come rimuovere entrambi questi caratteri extra per far funzionare il codice (e impostare Rectangle x = new Rectangle();)? – ganders

+1

a dire il vero, non vedo alcun motivo per cui hai bisogno della variabile 'local'; è usato solo per costruire 'pageBounds 'come riferimento. Sospetto che sia stata un'ottimizzazione del compilatore che confonde il decompilatore. Elimina semplicemente 'local' e costruisci direttamente un nuovo' pageBounds'. –

+0

davvero apprezzato Michael! – ganders

3

vedi qui - http://msdn.microsoft.com/en-us/library/aa664670(v=vs.71).aspx (avete mai usato però)

The prefix "@" enables the use of keywords as identifiers, che è utile quando ci si interfaccia con altri linguaggi di programmazione. Il carattere @ non è in realtà parte dell'identificatore, quindi l'identificatore potrebbe essere visto in altre lingue come un identificatore normale, senza il prefisso. Un identificatore con un prefisso @ è chiamato identificatore verbatim. È consentito l'uso del prefisso @ per identificatori che non sono parole chiave, but strongly discouraged as a matter of style.

L'esempio:

class @class 
{ 
    public static void @static(bool @bool) { 
     if (@bool) 
     System.Console.WriteLine("true"); 
     else 
     System.Console.WriteLine("false"); 
    } 
} 
class Class1 
{ 
    static void M() { 
     cl\u0061ss.st\u0061tic(true); 
    } 
} 
+2

Si prega di scrivere il motivo prima del downvoting. Abbia un bel coraggio! –