なぜ「システムを使用する」のか 悪い習慣とは考えていませんか?


47

私はC ++のバックグラウンドを持っており、この質問に対する回答を完全に理解して同意します。悪い習慣と考えていますか?

だから、C#の経験があると、正反対のことがわかり using Some.Namespace;ます。文字通りどこでも使用されています。タイプの使用を開始するときはいつでも、そのネームスペースのusingディレクティブを最初に追加します(まだ存在しない場合)。.csで始まらなかった-file を見たことを思い出せませんusing System; using System.Collections.Generic; using X.Y.Z; etc...。実際、Visual Studioウィザードを使用して新しいファイルを追加すると、必要がない場合でも、いくつかのusingディレクティブが自動的に追加されます。したがって、C ++コミュニティでは基本的にリンチされますが、C#でもこれを行うことを推奨しています。少なくともこれは私にはそれが見える方法です。

現在、C#とC ++でディレクティブを使用することはまったく同じではないことを理解しています。また、using namespaceC ++でできる最も厄介なことの1つ、つまりヘッダーファイルに配置することの1つは、ヘッダーファイルとの概念がないため、C#で同等に厄介なものがないことを理解しています#include

ただし、それらの違いにもかかわらず、C#とC ++でのディレクティブの使用は同じ目的に役立ちます。これはSomeType、ずっと長くするのではなく、常に入力するだけで済みますSome.Namespace.SomeType(C ++ ::ではの代わりに.)。これと同じ目的で、名前の衝突という危険も私には同じように見えます。

最良の場合、これによりコンパイルエラーが発生するため、修正する必要があるのは「のみ」です。最悪の場合でもコンパイルされ、コードは意図したものとは異なる動作をします。だから私の質問は:なぜ(どうやら)C#とC ++であまりにも悪いと考えられているディレクティブを使用しているのですか?

私が持っている答えのいくつかのアイデア(これらはどれも本当に私を満足させません):

  • 名前空間は、C ++よりもC#の方がはるかに長く、ネストされる傾向があります(stdvs. System.Collection.Generic)。したがって、この方法でコードのノイズを除去することには、より多くの欲求と利益があります。しかし、これが真実であっても、この議論は標準の名前空間を調べたときにのみ適用されます。カスタムのものには、C#とC ++の両方で、任意の短い名前を付けることができます。

  • 名前空間は、C ++よりもC#の方がはるかに「細かい」ように見えます。例として、C ++では標準ライブラリ全体std(およびのようないくつかの小さなネストされた名前空間chrono)が含まれますがSystem.IO、C#ではSystem.ThreadingSystem.Textなどがあります。したがって、名前の衝突のリスクは小さくなります。しかし、これはただの直感です。私は実際にどのように多くの名前を使用すると、「インポート」カウントされませんでしたusing namespace stdusing System。繰り返しになりますが、これが真実であっても、この議論は標準の名前空間を見たときにのみ適用されます。独自のものは、C#とC ++の両方で、必要に応じて細かく設計できます。

もっと議論はありますか?私は実際の難しい事実(もしあれば)に特に興味があり、意見にはあまり興味がありません。


2
@Timo OPはヘッダー汚染について明示的に尋ねていません
コンラッドルドルフ

1
これは、C ++と同じ程度のグローバル名前空間の競合がないためだと思いました(主にC標準ライブラリが原因です)。しかし、私は最もよく知っている人の答えを待っています。
Wyck

2
@ThomasWeller C ++では明らかです。C#では、Ext(this T t, long l)を介して呼び出される拡張メソッドを検討してくださいt.Ext(0)。次に、拡張メソッドを含む別の名前空間を追加するとExt(this T t, int i)、その名前空間が代わりに呼び出されます。しかし、私は(まだ)C#の専門家ではありません。
sebrockm

2
@Franckがあなたにその点を認めたとしても、同じ議論がC ++に適用され、C ++とC#の違いがわからないという私の疑問をさらに押し進めます
sebrockm

3
@Franck C ++は、あいまいな場合にコンパイラエラーをスローします。C#と同様。
ティモ

回答:


28

なぜ「システムを使用する」のか 悪い習慣とは考えていませんか?

「システムを使用して」されない普遍悪い習慣とは見なされません。たとえば、C#で 'using'ディレクティブを使用しないのはなぜですか。

しかし、それは非常に考慮されていないことは事実かもしれ悪いとしてなどusing namespace std。おそらく:

  1. C#にはヘッダーファイルがありません。プリプロセッサを使用して1つのC#ソースファイルを別のC#ソースファイルに「含める」ことは一般的ではありません。

  2. std名前空間はほぼフラットです。つまり、ほぼすべての標準ライブラリ関数、型、および変数がその中にあります(ファイルシステムサブ名前空間などの例外はほとんどありません)。非常に多くの識別子が含まれています。私の理解でSystemは、 含まれる名前ははるかに少なく、代わりにサブ名前空間が多くなっています。

  3. C#では、グローバル関数や変数はありません。そのため、グローバル識別子の数は、それらを含むC ++とは対照的に、通常は非常に少ないです。名前空間。

  4. 私の知る限り、C#には引数に依存するルックアップはありません。ADLを名前の非表示、オーバーロードなどと組み合わせて使用​​すると、一部のプログラムは名前の競合の影響を受けず、他のプログラムは微妙に影響を受ける場合があり、すべてのコーナーケースをテストで検出することは不可能です。

これらの違いがあるため、「システムを使用して」、名前が競合する可能性はに比べて低くなりusing namespace stdます。


それは、標準の名前空間をインポートするために、従来であれば、プログラマは従来通りになります。また、名前空間は自己永続大会、方法である「輸入」してみてくださいとの問題を軽減するのに役立つ、自分の識別子のためにその名前空間から名前を選ぶ避けるために、そのような慣習。

そのようなインポートが悪い習慣であると考えられるならば、プログラマーはインポートされた名前空間との衝突のそのような回避さえ試みる可能性が低くなります。そのため、たとえ選択肢間の議論の重みが元々微妙だったとしても、慣習は慣行に賛成するか反対するかのどちらかに偏極する傾向があります。


3
これは、名前空間を開くことの潜在的な欠点のみを考慮しています。これは始まりですが、利点も考慮する必要があると思います。C++の場合、ほとんどの場合、5文字(std::)節約できます。C#で、それが(実質的だSystem.「だけ」7つの文字を持っていますが、他の、ネストされた名前空間を持っている多くのより多くの文字を、そしてどこでもそれらを書くことはコードが完全に読めなくなるだろう)。
コンラッドルドルフ

C#のオーバーロードの解決がC ++の解決よりも優しく、多くのあいまいさがコンパイラエラーによって引き出されている場合もそうではありませんか?(信頼できると思われるあなたの答えに対する批判では決してありません。)
バトシェバ

3
@KonradRudolph欠点が重大であると見なされ、タイピングの量が(タイピングの量と比較して)同等に考慮される場合、非エイリアスを汚染する名前空間を代わりstd::に使用using Sys = System;するのは典型的なスタイルではありませんusingか?
eerorika

2
「権威ある」に関する@Bathsheba、私はC#についてほとんど知らないことを放棄したいと思います。私の答えはC ++の知識とC#に関するいくつかのgoogle検索に基づいています。だから、誰かがC#の部分を実際にチェックしてくれれば
幸いです

2
ADLの部分について:C#には拡張メソッドがあります。これはADLとは異なるデザインですが、名前の競合に関する同じ問題を共有しています。
ティモ

-2

ただし、C#とC ++でディレクティブを使用しても、Some.Namespace.SomeTypeをもっと長くする必要はありません(C ++では::ではなく::を使用します)。そして、同じ目的で、名前の衝突が私には危険であるように見えます。

はい、しかしあなたはその危険をエクスポートしませんでした(読んでください:他の人にそれを処理することを強制します):

現在、C#とC ++でディレクティブを使用することはまったく同じではないことを理解しています。また、C ++で名前空間を使用してできる最も厄介なことの1つ、つまりヘッダーファイルに配置することは、ヘッダーファイルと#includeの概念がないため、C#では同等のものがないことも理解しています。

ですから、それはむしろ別のカテゴリーのものです。

また、C ++は、C#のようにIDEで開発するように「設計」されていません。C#は、基本的には常にIntellisenseを含むVisual Studioで記述されています。それを作成した人々がそのように使用するように設計されています。IDEを使用してC ++で開発する人の数に関係なく、IDEはその使用例を圧倒的な懸念事項として設計されていません。

名前空間は、C ++よりもC#の方がはるかに「細かい」ように見えます。

はい、それも。using namespace stdそしてusing System.Collection.Generic比類のないです。

それらを比較しないでください!


2
これはOPの懸念には答えません。これは、ヘッダーで名前空間を開くことではなく、実装ファイルで開くことに関するものです
Konrad Rudolph

2
@KonradRudolph using namespace stdC ++で避けるべきアドバイスは、主にヘッダーファイルに関するものです。答え、これはC#では適用されないということです。
翼のある小惑星

8
@AsteroidsWithWings避けるべきアドバイスusing namespace stdは確かにほとんどヘッダーについてではありません。ヘッダーでの使用は危険です。実装での使用はお勧めしません。
トミーアンデルセン

1
using namespace ...C ++で避けるべきアドバイスはusing、名前の衝突を回避することです。C#のディレクティブは、名前の衝突の可能性も導入しています。実装は異なりますが。
トミーアンデルセン

@TommyAndersen、このような競合が発生した場合、その解決はどれほど難しいですか?1秒かかります。C# using宣言は単一のタイプ/クラスを定義するファイルごとであり、タイプは通常、比較的狭いアプリケーションドメインの概念(理想的には単一の責任の原則)のセットと関係があるため、このような名前空間の衝突の確率は非常に低くなります。しかし、いつ起こるかは簡単に修正できます。一般的な.NET開発ツール/ IDEは、それを支援します。複数の開発アクティビティの最高のものを組み合わせることで生産性を向上させるように設計された開発エコシステム全体を検討してください
AKornich
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.