对象类型末尾的与号字符是什么
本文关键字:字符 是什么 类型 对象 | 更新日期: 2023-09-27 18:37:22
我不得不反编译一些代码,我不知道这个语法是什么?你们能帮忙,或者给我写一篇关于它是什么的文章吗?我已经用谷歌搜索了这个网站,但找不到任何东西。
只需一行代码:
Rectangle pageBounds;
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
Rectangle& local = @pageBounds;
矩形对象类型末尾的@
符号和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;
}
那行代码前面的注释准确地告诉你发生了什么。类型名称后面的&
表示它是引用类型,变量名称前面的@
生成对该变量的引用。
(@
符号也可以在 C# 代码中用于转义关键字以用作变量名称,但这不是这里发生的事情。 pageBounds
不是 C# 关键字。
请注意,这不是有效的 C# 语法 - 不能引用 C# 中的局部变量,尽管 CLR 支持它。(注意:从 C# 7.0 开始,这不再是正确的;此处描述了语法,但它不使用&
因此此反编译代码仍然是无效的 C#)。
例如,当您使用ref
和out
参数时,会隐式创建对局部变量的引用,但使用关键字而不是显式键入参数作为引用。(例如,如果你有一个out int x
,在内部该变量是 Int32&
类型。如果代码是合法的 C#,则代码的意图是 pageBounds
和 local
是具有两个不同名称的同一实例;你对一个人做的任何事情都会发生在另一个身上。因此,例如,此非法代码:
Rectangle pageBounds;
Rectangle& local = @pageBounds;
local = new Rectangle();
将与此法典相同:
Rectangle pageBounds = new Rectangle();
如果尝试将代码编译为反编译代码,则会收到错误,因为编译器将&
视为按位和运算符,并且会抱怨您使用的类型就好像它是变量一样。但这没关系,因为您不是从 C# 源文件中获取的。你反编译了一个 IL 方法来获取它,你可以在 IL 中做很多在 C# 中是非法的事情。当您反编译代码时,这种情况一直发生;例如,您会看到非法的类和方法名称。这只是意味着编译器基于原始代码生成 IL,该代码不会直接转换回 C#,但会按照您想要的方式运行。您返回的代码只是反编译器从它拥有的 IL 生成 C# 代码的最佳尝试。
您可以在有关它们的众多 Jetbrains 错误报告中查看生成这些引用的代码示例:
- http://youtrack.jetbrains.com/issue/DOTP-521
- http://youtrack.jetbrains.com/issue/DOTP-1077
- http://youtrack.jetbrains.com/issue/DOTP-524
看这里 - 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);
}
}