【问题标题】:What is the ampersand character at the end of an object type?对象类型末尾的 & 字符是什么?
【发布时间】:2012-06-16 22:05:51
【问题描述】:

我不得不反编译一些代码,但我不知道这个语法是什么?你们能帮忙吗,或者指点我写一篇关于它是什么的文章?我用 Google 搜索并搜索了这个网站,但找不到任何东西。

只有一行代码:

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;
}

【问题讨论】:

  • 阅读参考资料和指针
  • @MichaelDibbets:这是 C#...
  • C# 有引用、指针、值类型;)
  • 混淆了重新标题和正文...&amp; 是“和”(标题),@ 是“at”(正文)-您在问什么?
  • @MarcGravell 实际上,两者都是。应该改变我的标题...

标签: c# decompiling reflector


【解决方案1】:

该行代码之前的 cmets 会准确地告诉您发生了什么。类型名称后的&amp; 表示它是引用类型,变量名称前的@ 生成对该变量的引用。

@ 符号也可以在 C# 代码中用于 escape 关键字以用作变量名,但这不是这里发生的情况。pageBounds 不是 C# 关键字。)

请注意,这不是有效的 C# 语法——您不能在 C# 中引用局部变量,尽管 CLR 支持它。 (注意:从 C# 7.0 开始,这不再适用;语法描述为 here,但它不使用 &amp;,因此这个反编译的代码仍然是无效的 C#。

例如,当您使用 refout 参数时,会隐式创建对局部变量的引用,但是使用关键字而不是显式键入参数作为引用。 (例如,如果您有一个 out int x,则该变量内部的类型为 Int32&amp;。)如果它是合法的 C#,代码的 intent 将是 pageBoundslocal 同一个实例有两个不同的名字;你对一个人所做的任何事情都会发生在另一个人身上。因此,例如,这个非法代码:

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

将与本法典相同:

Rectangle pageBounds = new Rectangle();

如果你试图将代码编译为反编译,你会得到一个错误,因为编译器将&amp; 视为bitwise and 运算符,并且会抱怨你使用了一个类型,就好像它是一个变量一样。但这没关系,因为您不是从 C# 源文件中获取它的。你反编译了一个IL方法来得到它,你可以在IL中做很多在C#中是非法的事情。当您反编译代码时,这种情况总是会发生;例如,您会看到非法的类和方法名称。这只是意味着编译器基于原始代码生成 IL,该代码不会直接转换回 C#,但 以您想要的方式运行。您返回的代码只是反编译器从其拥有的 IL 生成 C# 代码的最佳尝试。

您可以在大量 Jetbrains 错误报告中看到生成这些引用的代码示例:

【讨论】:

  • 很棒的答案。谢谢你的解释,现在有点道理。对于我的情况,是否像删除这两个额外的字符以使代码正常工作(并设置 Rectangle x = new Rectangle();) 一样简单?
  • 说实话,我看不出有任何理由需要local 变量;它仅用于通过引用构造pageBounds。我怀疑这是一个让反编译器感到困惑的编译器优化。只需去掉local,直接构造一个新的pageBounds即可。
  • 真的很感谢迈克尔!
【解决方案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);
   }
}

【讨论】:

  • 请在投票前写下原因。有一些真正的胆量!
猜你喜欢
  • 1970-01-01
  • 2019-09-06
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多