.NETは参照の戻りをサポートしていますが、C#はサポートしていないことを読みました。特別な理由はありますか?なぜ私は次のようなことができないのですか?
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
return ref x
C# 7
:)
.NETは参照の戻りをサポートしていますが、C#はサポートしていないことを読みました。特別な理由はありますか?なぜ私は次のようなことができないのですか?
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
return ref x
C# 7
:)
回答:
この質問は、2011年6月23日の私のブログの主題でした。すばらしい質問をありがとう!
C#チームはC#7でこれを検討しています。詳細については、https://github.com/dotnet/roslyn/issues/5233を参照してください。
更新:この機能はC#7に組み込まれました!
あなたは正しいです; .NETは、変数へのマネージ参照を返すメソッドをサポートしています。.NETは、他の変数へのマネージ参照を含むローカル変数もサポートしています。(ただし、.NETは、ガベージコレクションのストーリーを非常に複雑にするため、他の変数へのマネージド参照を含むフィールドまたは配列をサポートしていません。また、「変数へのマネージド参照」タイプは、オブジェクトに変換できないため、ジェネリック型またはメソッドへの型引数。)
コメンター「RPM1984」は何らかの理由でこの事実の引用を求めました。RPM1984この.NETの機能については、CLI仕様のパーティションIのセクション8.2.1.1「マネージドポインタと関連するタイプ」を読むことをお勧めします。
これらの両方の機能をサポートするバージョンのC#を作成することは完全に可能です。その後、次のようなことができます
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
そしてそれを
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
私はそうしたので、これらの機能をサポートするバージョンのC#をビルドすることが可能であることを経験的に知っています。高度なプログラマー、特にアンマネージC ++コードを移植する人々は、実際にポインターを使用してメモリをどこにでも固定するという大きなハンマーを使わずに、参照を使用してC ++に似た機能を要求することがよくあります。管理された参照を使用することにより、ガベージコレクションのパフォーマンスを台無しにするコストを支払うことなく、これらの利点を得ることができます。
私たちはこの機能を検討し、実際に実装して他の社内チームにフィードバックを表示できるようにしました。ただし、現時点では、Googleの調査によると、この機能は、実際にサポートされている言語機能にするための十分な広さや説得力のある使用例がないと考えています。他にも高い優先順位があり、利用できる時間と労力には限りがあるため、この機能をすぐに実行する予定はありません。
また、適切に行うには、CLRに変更を加える必要があります。現在、CLRはref-returningメソッドを正当であるが検証できないものとして扱います。これは、この状況を検出する検出器がないためです。
ref int M1(ref int x)
{
return ref x;
}
ref int M2()
{
int y = 123;
return ref M1(ref y); // Trouble!
}
int M3()
{
ref int z = ref M2();
return z;
}
M3はM2のローカル変数の内容を返しますが、その変数の寿命は終了しています!スタックの安全性に明らかに違反しない ref-returnsの使用を決定する検出器を作成することは可能です。私たちがやろうとしていることは、そのような検出器を記述し、検出器がスタックの安全性を証明できなかった場合、プログラムのその部分でのref戻りの使用を許可しません。これを行うのは膨大な開発作業ではありませんが、実際にすべてのケースを確実に取得することを確認することは、テストチームの負担となります。これは機能のコストを増加させるもう1つの理由であり、現時点ではコストを上回るメリットはありません。
この機能が必要な理由を説明していただければ幸いです。実際の顧客がなぜそれを必要としているのかについての情報が多いほど、いつか製品に組み込まれる可能性が高くなります。かわいらしい機能ですので、興味がありましたらなんとかしてお客様にお届けしたいと思います。
(また、関連の質問を参照してください。C#で変数への参照を返すことは可能ですか?と++私はCのようなC#関数の内部リファレンスを使用することはできますか?)
y
てきた後も生き続けるのに適していませんM2
か?私はこの機能が地元住民を捕らえるラムダのように機能することを期待します。それとも、CLRがそのシナリオを処理する方法であるため、提案した動作ですか?
あなたは値型への参照を返すメソッドについて話している。私が知っている唯一のC#の組み込み例は、値型の配列アクセサーです。
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
そして、その構造体の配列を作成します:
var points = new Point[10];
points[0].X = 1;
points[0].Y = 2;
この場合points[0]
、配列インデクサーはstructへの参照を返します。これと同じ「参照を返す」動作を持つ独自のインデクサー(たとえば、カスタムコレクション用)を作成することはできません。
私はC#言語を設計しなかったので、それをサポートしないことの背後にあるすべての理由はわかりませんが、簡単な答えは次のとおりだと思います。