对象类型末尾的“&"字符是什么? [英] What is the ampersand character at the end of an object type?

查看:151
本文介绍了对象类型末尾的“&"字符是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不得不反编译一些代码,但我不知道这种语法是什么?你们可以帮忙吗,或指向我写一篇有关它的文章吗?我已经用Google搜索并搜索了该站点,但找不到任何内容.

I had to de-compile some code and I don't know what this syntax is? Can y'all help, or point me to a write-up about what it is? I've Googled and searched this site and can't find anything.

只需一行代码:

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

Rectangle对象类型结尾处的@符号是什么,pageBounds变量之前的@是什么?

What is the @ symbol at the end of the Rectangle object type, and the @ before the pageBounds variable?

这是我需要修复的最后一行代码,以便使该可执行文件再次编译.

This is my last line of code that I need to fix in order to get this executable to compile again.

这是使用此语法的方法,我可以摆脱它吗?

Here's the method that uses this syntax, can I get away with removing it?

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

推荐答案

该行代码之前的注释正在告诉您正在发生的事情. &类型名称后的符号表示它是引用类型,变量名称前的@表示对该变量的引用.

The comments right before that line of code are telling you exactly what's going on. The & sign after a type name indicates that it's a reference type, and the @ before a variable name generates a reference to that variable.

(@符号也可以在C#代码中用于转义"用作变量名的关键字,但这不是这里所发生的事情."pageBounds"不是C#关键字.)

(The @ sign can also be used in C# code to "escape" keywords for use as variable names but that's not what is happening here. "pageBounds" is not a C# keyword.)

请注意,这不是有效的C#语法-尽管CLR支持,但您无法引用C#中的局部变量. (注意:从C#7.0开始,这不再成立;语法在

Note that this is not valid C# syntax -- you cannot take a reference to a local variable in C#, although the CLR supports it. (NOTE: As of C# 7.0, this is no longer true; the syntax is described here, but it does not use the & so this decompiled code is still invalid C#).

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

Creating a reference to a local variable happens implicitly when you use ref and out parameters, for example, but the keywords are used instead of explicitly typing the parameters as reference. (e.g. if you had an out int x, internally that variable is of type Int32&.) The intent of the code, if it were legal C#, would be that pageBounds and local were the same instance with two different names; anything you do to one happens to the other. So, for example, this illegal code:

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

将与此法律代码相同:

Rectangle pageBounds = new Rectangle();

如果您尝试按反编译的方式编译代码,则会因编译器将&作为按位和,并且会抱怨您使用的类型就好像它是一个变量一样.但这没关系,因为您没有从C#源文件中获得它.您反编译了一个IL方法来获取它,并且您可以在IL中做很多事,这些事在C#中是非法的.当您反编译代码时,这种情况一直发生.您会看到例如非法的类和方法名称.这仅表示编译器基于原始代码生成了IL,该原始代码不会直接转换回C#,而是表现所需的方式.您要获取的代码很简单,反编译器将根据其拥有的IL生成C#代码的最佳尝试.

If you tried to compile the code as-decompiled, you would get an error because the compiler treats & as the bitwise and, and will complain that you used a type as if it were a variable. But that's ok because you didn't get it from a C# source file. You decompiled an IL method to get it, and there are a lot of things you can do in IL that are illegal in C#. This happens all the time when you decompile code; you see illegal class and method names for example. It just means that the compiler generated IL based on the original code that does not translate directly back into C#, but behaves the way you wanted. The code you are getting back is simple the decompiler's best attempt to produce C# code from the IL it has.

在众多有关它们的Jetbrains错误报告中,您可以看到生成这些引用的各种代码示例:

You can see examples of the sort of code that produces these references in the numerous Jetbrains bug reports about them:

  • http://youtrack.jetbrains.com/issue/DOTP-521
  • http://youtrack.jetbrains.com/issue/DOTP-1077
  • http://youtrack.jetbrains.com/issue/DOTP-524

这篇关于对象类型末尾的“&"字符是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆