[解決済み] object-lifetime-extending-closure はC#コンパイラのバグか?
2022-06-17 09:02:38
質問
私は 質問 の質問に答えているときに、クロージャがオブジェクトの寿命を(合法的に)延長する可能性について、私はいくつかの 非常に C# コンパイラー (これが重要なら 4.0) の一部で、非常に不思議なコード生成に遭遇したときです。
私が見つけた最短のレプロは次のとおりです。
- を呼び出しながら、ローカルをキャプチャするラムダを作成する。 静的 メソッドを呼び出すラムダを作成します。
- 生成されたデリゲートリファレンスを インスタンス フィールドに割り当てます。
結果 コンパイラは、ラムダを作成したオブジェクトを参照するクロージャオブジェクトを作成します。
静的
メソッドであり、ラムダを生成したオブジェクトのインスタンスメンバはデリゲート実行時に触れる必要がない(そして触れていない)。事実上、コンパイラはプログラマが捕捉した
this
を意味なく捕捉したように振る舞います。
class Foo
{
private Action _field;
public void InstanceMethod()
{
var capturedVariable = Math.Pow(42, 1);
_field = () => StaticMethod(capturedVariable);
}
private static void StaticMethod(double arg) { }
}
リリースビルドから生成されたコード(「より単純な」C#にデコンパイルされたもの)は、次のようになります。
public void InstanceMethod()
{
<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.<>4__this = this; // What's this doing here?
CS$<>8__locals2.capturedVariable = Math.Pow(42.0, 1.0);
this._field = new Action(CS$<>8__locals2.<InstanceMethod>b__0);
}
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public Foo <>4__this; // Never read, only written to.
public double capturedVariable;
// Methods
public void <InstanceMethod>b__0()
{
Foo.StaticMethod(this.capturedVariable);
}
}
を見てみると
<>4__this
フィールドにオブジェクトの参照が入力されますが、決して読み込まれません (理由はありません)。
では、どうなっているのでしょうか?言語仕様はそれを許可しているのでしょうか。 これはコンパイラーのバグ/奇妙さなのか、それともクロージャーがオブジェクトを参照する正当な理由 (私が明らかに見逃しているもの) があるのでしょうか。これは、クロージャを好むプログラマ (私のような) が、知らず知らずのうちにプログラムに奇妙なメモリ リーク (デリゲートがイベント ハンドラとして使用された場合を想像してください) を導入するレシピのように見えるので、私を不安にさせます。
どのように解決するのですか?
それは確かにバグのように見えます。私に注意を促してくれてありがとうございます。調査してみます。すでに発見され、修正されている可能性もあります。
関連
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み】Nullableオブジェクトは値を持たなければならない?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?