2009-03-03 7 views
8

私はポインタを理解しており、まれにC#コードでそれらを使用する必要があります。私の質問は、コードブロックに「安全でない」と明示的に述べなければならない理由は何か。さらに、「安全でない」コードを許可するためにコンパイラオプションを変更する必要があるのはなぜですか?C#:「安全でない」/コンパイラオプションを明示的に指定する利点

ボトムライン:何CLR(または言語仕様)で、我々はいつでも、それは私たちだけで(多くのCおよびC++のような)「安全でない」と入力し、コンパイラオプションを変更することなく、ポインタを使用することはできませんになり?

説明のために:私は「安全でない」コードと「安全な」コードが何であるか知っています。これは、これらの機能を使用できるようにするために、余分な作業をすべて行う必要がある(なぜなら、それほど余分ではない)ということの問題です。

答えて

9

hereに触れるC#Creator Anders Hejlsbergとのインタビューがあります。基本的に、まさに@Marc Gravellが言ったこと:まずタイプセーフで、明示的宣言では安全ではない。

あなたの質問に答えてください:CLRの何もそれを妨げるものはありません。これは、タイプを扱うときに安全手袋で作業できるように設計された言語イディオムです。手袋を外したい場合、それはあなたの選択ですが、手袋を外すための積極的な選択をしなければなりません。

編集:明確にするため

:私は は、 "安全でない" と "安全" のコードが何であるかを知っています。それはちょうど 余分な仕事(大したことではない)を行う必要がある理由の質問 これらの機能を使用できるようにするためです。

私がリンクしたインタビューで触れたように、それは明示的なデザイン決定でした。 C#は本質的にJavaの進化であり、Javaでは、ポインタはまったくありません。しかし、デザイナーはポインタを許可したかった。しかし、C#は通常Java開発者を連れてくるので、のデフォルトのの動作がJavaと似ている、すなわちポインタがない場合でも、明示的な宣言によるポインタの使用が可能であることが最良であると感じました。

「余分な仕事」は、あなたがそれをする前に何をしているのかを考えるように強制することを意図しています。明示的に言えば、少なくとも次のことを考慮する必要があります。「なぜ私はこれをやっているのですか?本当にに参照型があればポインタが必要ですか?

7

大部分は検証可能です。 unsafeと記載することで、手袋はオフになります。システムはあなたのコードがアモックにならないことを保証できなくなります。ほとんどの場合、セーフゾーンに滞在することが非常に望ましいです。

これは、部分的な信頼(addinsなど)でより顕著になりますが、通常のコードではまだ価値があります。

+0

基本的に、それはC++で作るのがずっと簡単だったのと同じミスをやめさせようとしているのですか? – Inisheer

+1

低レベルのAPI呼び出しを行う、ポインタ演算を使用する、またはその他の不快な操作を行うMS:C#コードから、unsafeキーワードでマークされたブロックの中に配置する必要があります。 – VBNight

+0

# からMS:場合によっては、安全でないコードが配列の境界チェックを削除してアプリケーションのパフォーマンスを向上させることがあります。 – VBNight

1

だから、など、良い習慣に&セキュリティを育成

1

昇格されたアクセス許可なしに、Webサービスでは動作しませんどのコードすぐに明らかであること。アセンブリ内で安全でないブロックを使用するたびに、NativeCodeパーミッションがスタックから要求されます。もちろんこれは暗黙的に行うこともできますが、プライベートキーワードを完全に削除することはできませんか?開発者に安全でないコードが必要なことを明示的に要求してから使用することをお勧めします。

2

安全でないブロックを使用すると、コードを確認できないようにする効果があります。これには特定のアクセス許可が必要で、出力に許可したくない場合(特に共有ソース環境の場合)、コンパイラにスイッチを許可しないようにするスイッチがあります。

2

は逆の観点から、それについて考える:それは危険なマークされていないので、あなたは、ほとんどのコードは、デフォルトでは「安全」であることを推測することができます。では、「安全」であることは何を意味していますか? .Netコードの場合、これには次のものが含まれます(ただしこれに限定されない場合があります)。

  • ガベージコレクタは通常どおりビジネスを行うことができます。
  • 特定のタイプへの参照は、そのタイプのオブジェクト(またはnull)を参照します。
  • コードは.Netの信頼/セキュリティ要件に準拠することが保証されています。
  • コードは、それ自身のAppDomain外のメモリに直接触れないことが数学的に証明されています。あなたは同じアプリケーション内に複数のAppDomainsを持っていると想像してみてください。プログラマは、それらを確実に論理的に分離して扱うことができます。

いつでもポインタを使用すると、これらの保証のいずれかを破る可能性があります。したがって、コードを安全でないものとしてマークすると、それらの保護が放棄されます。

1

安全なコードと安全でないコードの最も大きな違いは、安全でないコードが.netのガベージコレクタに到達できないことです。 Automatic GCは、.netの中でも大きな部分を占めています。境界を越えると、コードについて何が想定できるのかが大きく変わります。

ポインタは特に、GC参照のないヒープ上のオブジェクトの作成を可能にします。これにより、コードに「安全でない」とマークするよう要求する別の優れた理由が生まれます。メモリリークが発生している場所がわかったときに、その場所を簡単に絞り込むことができます。

3

実際には、CLRは、安全でないスイッチやキーワードについてはまったく必要ありません。実際、C++/CLI(CLRで実行されるC++言語)には、そのような/安全でないスイッチはなく、ポインタはCLR上で自由に使用できます。 「ポインタを使用することができます前に、なぜC#は危険なの使用を/必要ない?」と

は、だから私はあなたの質問を言い換えますその質問に対する答えは、ここで与えられた他の回答に記載されているとおりです。ユーザーが意識的にCLRの完全信頼モードよりも低いレベルで実行する意思決定を下すのを助けるためです。フルトラストが必要なコードを呼び出すたびに、またはポインタを使用するたびに、C++はCLRの完全信頼を常に必要とし、C#になります。

+0

正確に。私は以前の "ボトムライン"の部分を言い換えました。私はC++/CLIをかなり頻繁に使用しています。そして、実際にはC#についてこの質問をしています。 – Inisheer

2

要するに、.NETはあなたの意図を述べることを望んでいます。

確かに、コンパイラは「安全でない」フラグの必要性を推測することができます。しかし、デザイナーはそれが意図的な決定であることを望んでいます。

  • 休憩なしなしスイッチケース
  • なしアクセスレベルな「公共:」として「セクション」(:Cでのマーカー++私に

    は、それはC#での構文的な要件の数に似てます)「VAR」を使用して

  • なしクラスフィールド

パターンを使用すると、別の影響を与えるうっかり移動したり、一つのことを変更してはならないということです。理由のなかで、彼らはあなたを「足に自分を撃つ」から守りたいと思っています。

たくさんの有益な回答がここにあります—これはあなたの質問にもっと役立つかもしれません。

関連する問題