Что такое символ амперсанда в конце типа объекта?
Мне пришлось декомпилировать какой-то код, и я не знаю, что это за синтаксис? Могу ли я помочь, или назовите меня записью о том, что это такое? Я googled и искал этот сайт и ничего не могу найти.
Только одна строка кода:
Rectangle pageBounds;
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
Rectangle& local = @pageBounds;
Что такое "&" символ в конце типа объекта Rectangle и "@" перед переменной pageBounds?
Это моя последняя строка кода, которую мне нужно исправить, чтобы этот исполняемый файл снова скомпилировался.
В этом методе, который использует этот синтаксис, я могу уйти с его удалением?
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
Комментарии прямо перед этой строкой кода сообщают вам, что именно происходит. Знак и знак после имени типа указывают, что это ссылочный тип, а @перед именем переменной генерирует ссылку на эту переменную.
(Знак @также может использоваться в коде С# для "escape" ключевых слов для использования в качестве имен переменных, но это не то, что здесь происходит. "pageBounds" не является ключевым словом С#.)
Обратите внимание, что это недопустимый синтаксис С# - вы не можете взять ссылку на локальную переменную в С#. Это происходит неявно, если вы используете, например, параметры ref
и out
, но ключевые слова используются вместо того, чтобы явно вводить параметры в качестве ссылки. (например, если у вас есть out int x
, внутренне эта переменная имеет тип Int32&
.) Целью кода, если бы он был законным С#, было бы то, что pageBounds
и local
были тем же экземпляром с двумя разными имена; все, что вы делаете с одним, происходит с другим. Так, например, этот незаконный код:
Rectangle pageBounds;
Rectangle& local = @pageBounds;
local = new Rectangle();
будет таким же, как этот юридический код:
Rectangle pageBounds = new Rectangle();
Если вы попытались скомпилировать код как декомпилированный, вы получите ошибку, потому что компилятор рассматривает и как побитовое, и будет жаловаться на то, что вы использовали тип, как если бы он был переменной. Но это нормально, потому что вы не получили его из исходного файла С#. Вы декомпилировали IL-метод, чтобы получить его, и есть много вещей, которые вы можете сделать в IL, которые являются незаконными в С#. Это происходит все время, когда вы декомпилируете код; например, вы видите недопустимые имена классов и методов. Это просто означает, что компилятор сгенерировал IL на основе исходного кода, который не переводится непосредственно на С#, но ведет себя так, как вы хотели. Код, который вы возвращаете, является простой декомпиляционной попыткой создать код С# из ИЛ, который он имеет.
Вы можете увидеть примеры кода, который создает эти ссылки в многочисленных отчетах об ошибках Jetbrains о них:
Ответ 2
Смотрите здесь - http://msdn.microsoft.com/en-us/library/aa664670(v=vs.71).aspx (никогда не использовали)
The prefix "@" enables the use of keywords as identifiers
, что полезно при взаимодействии с другими языками программирования. Символ @на самом деле не является частью идентификатора, поэтому идентификатор можно увидеть на других языках в качестве обычного идентификатора без префикса. Идентификатор с префиксом @называется стенографическим идентификатором. Использование префикса @для идентификаторов, которые не являются ключевыми словами, разрешено, but strongly discouraged as a matter of style
.
Пример:
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);
}
}