14

一部のコードを逆コンパイルする必要がありましたが、この構文が何であるかわかりません。助けてくれますか、それが何であるかについての記事を教えてくれませんか? このサイトをグーグルで検索して検索しましたが、何も見つかりません。

たった 1 行のコード:

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

2 に答える 2

24

そのコード行の直前のコメントは、何が起こっているかを正確に伝えています。型名の後の & 記号は参照型であることを示し、変数名の前の @ はその変数への参照を生成します。

(@ 記号は、変数名として使用するためにキーワードを「エスケープ」するために C# コードで使用することもできますが、ここではそうではありません。「pageBounds」は C# キーワードではありません。)

これは有効な C# 構文ではないことに注意してください。CLR ではサポートされていますが、C# ではローカル変数への参照を取得できません。(注: C# 7.0 の時点では、これは当てはまりません。構文はここで説明されていますが、 を使用していないため、&この逆コンパイルされたコードはまだ無効な C# です)。

たとえば、パラメーターを使用すると、ローカル変数への参照が暗黙的に作成されますが、参照としてパラメーターを明示的に入力する代わりに、キーワードが使用されrefます。out(たとえば、 があった場合out int x、内部的にその変数の型はInt32&です。)コードの意図は、それが正当な C# である場合、それでpageBoundsあり、2 つの異なる名前を持つ同じインスタンスlocalでした。あなたが一方に対して行うことは、他方にも起こります。たとえば、この不正なコードは次のとおりです。

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

は、次の法的コードと同じになります。

Rectangle pageBounds = new Rectangle();

コードを逆コンパイルしてコンパイルしようとすると、コンパイラは & をビットごとの and として扱い、変数であるかのように型を使用したと不平を言うため、エラーが発生します。しかし、C# ソース ファイルから取得したのではないので問題ありません。それを取得するためにIL メソッドを逆コンパイルしました。ILで実行できることは、C# では違法なことがたくさんあります。これは、コードを逆コンパイルするときに常に発生します。たとえば、不正なクラス名やメソッド名が表示されます。これは、コンパイラが元のコードに基づいて IL を生成したことを意味します。このコードは直接 C# に変換されるのではなく、希望どおりに動作します。返されるコードは単純で、逆コンパイラが持っている IL から C# コードを生成する最善の試みです。

これらの参照を生成するコードの種類の例は、それらに関する多数の Jetbrains バグ レポートで確認できます。

于 2012-06-16T22:49:58.980 に答える
3

ここを参照してください - 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);
   }
}
于 2012-06-16T22:11:48.670 に答える