2012-06-16 14 views
11

Tuve que compilar un código y no sé qué es esta sintaxis. ¿Puede ayudar o indicarme un artículo sobre lo que es? Busqué en Google y en este sitio y no puedo encontrar nada.¿Cuál es el carácter ampersand al final de un tipo de objeto?

una sola línea de código:

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

cuál es el símbolo "&" al final del tipo de objeto rectangular, y el "@" antes de la variable pageBounds?

Esta es mi última línea de código que necesito corregir para que este ejecutable se vuelva a compilar.

Este es el método que usa esta sintaxis, ¿puedo salirse con la suya?

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

leer sobre referencias y punteros – Tschallacka

+0

@MichaelDibbets: Esto es C# ... – Ryan

+0

C# tiene referencias, punteros, * y * valor t ypes;) –

Respuesta

19

Los comentarios justo antes de que la línea de código que le están diciendo exactamente lo que está pasando. El signo & después de un nombre de tipo indica que es un tipo de referencia, y el @ antes de un nombre de variable genera una referencia a esa variable.

(El signo @ puede también ser utilizado en C# código para "escapar" palabras clave para su uso como nombres de variables, pero eso no es lo que está pasando aquí. "PageBounds" no es un C# palabra clave.)

Tenga en cuenta que este no es una sintaxis válida de C#; no puede tomar una referencia a una variable local en C#. Esto ocurre implícitamente cuando usa los parámetros ref y out, por ejemplo, pero las palabras clave se usan en lugar de escribir explícitamente los parámetros como referencia. (., Por ejemplo, si ha tenido una out int x, internamente esa variable es de tipo Int32&) La intención del código, si fuera legal C#, sería que pageBoundslocal y eran la misma instancia con dos nombres diferentes; cualquier cosa que le hagas a uno le pasará al otro. Así, por ejemplo, este código ilegal:

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

sería el mismo que el código legal:

Rectangle pageBounds = new Rectangle(); 

Si se trató de compilar el código como-descompilación, se llega a un error debido a que el el compilador trata & como bit a bit y, y se quejará de que utilizó un tipo como si fuera una variable. Pero eso está bien porque no lo obtuviste de un archivo fuente de C#. Usted decompiló un método IL para obtenerlo, y hay muchas cosas que puede hacer en Illinois que son ilegales en C#. Esto ocurre todo el tiempo cuando descompilas el código; ves nombres ilegales de clases y métodos, por ejemplo.Simplemente significa que el compilador generó IL basado en el código original que no se traduce directamente de nuevo a C#, pero se comporta de la manera que usted desea. El código que está recibiendo es simple, el mejor intento del decompilador para producir código C# del IL que tiene.

Se puede ver ejemplos del tipo de código que produce estas referencias en los numerosos informes de errores de JetBrains sobre ellos:

+0

fantástica respuesta. Gracias por la explicación, tiene sentido ahora. Para mi situación, ¿es tan fácil como eliminar ambos caracteres extra para hacer que el código funcione (y establecer el Rectángulo x = new Rectangle();)? – ganders

+1

para ser honesto, no veo ningún motivo por el que necesite la variable 'local'; solo se usa para construir 'pageBounds' por referencia. Sospecho que fue una optimización del compilador que confunde al decompilador. Simplemente elimine 'local' y construya un nuevo' pageBounds' directamente. –

+0

realmente lo aprecio Michael! – ganders

3

ve aquí - http://msdn.microsoft.com/en-us/library/aa664670(v=vs.71).aspx (aunque nunca han usado)

The prefix "@" enables the use of keywords as identifiers, lo cual es útil cuando la interconexión con otros lenguajes de programación. El carácter @ no es realmente parte del identificador, por lo que el identificador podría verse en otros idiomas como un identificador normal, sin el prefijo. Un identificador con un prefijo @ se denomina identificador literal. Se permite el uso del prefijo @ para los identificadores que no son palabras clave, but strongly discouraged as a matter of style.

El ejemplo:

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

Escriba la razón antes de la votación a favor. ¡Ten algo de valor! –

Cuestiones relacionadas