web-dev-qa-db-ja.com

C#でプライベートクラスを作成できますか?

これは、.NET哲学者への質問です。

MicrosoftがC#でのプライベートクラスの使用を意識的に拒否したことは私の理解です。なぜ彼らはこれをしたのですか、そしてそうするための彼らの議論は何ですか?

たとえば、私はレポートツールを含む大規模なアプリケーションを構築しています。このツールは、レポートツール内でのみ使用され、プロジェクトの他の部分では使用されない多くのビジネスオブジェクトを使用します。レポートツール自体でのみ使用できるようにカプセル化したい。

大きな決断は、このツール用にVSで別のプロジェクトを作成することです。私はそれをやりますが、興味深いことに、これができない場合はどうなりますか。たとえば、アーキテクチャが十分ではなく、大きなシングルがあります。事業。

「プライベートクラス」の背後にあるのは、それ自体を除いて、他の名前空間では使用できないクラスを意味します。

私の質問はそうではありませんでした-どうすればこれをシミュレートできますか、または別の方法で行うことができます。親クラスなしでクラスキーワードとプライベートキーワードを使用しないのはなぜかと思っています。何らかの理由があるはずだと思います。そして私はそれを知りたいです

23
Archeg

これには回避策がありますが、気に入らない場合があります。

namespaceを使用してクラスのスコープを設定する代わりに、public static partial classを使用します。

前:

namespace MyCompany.Foo {
  class Bar { }
  public class Baz { }
}

後:

namespace MyCompany {
  public static partial class Foo {
    private class Bar { }
    public class Baz { }
  }
}

この構造は、名前空間と同様に、同じプロジェクト内の複数のファイルにまたがることができます。ただし、名前空間とは異なり、プロジェクトから「エスケープ」することはできません(他のプロジェクトはFoo内で他のメンバーを定義できません)。

Foo内のコードに対して クラスがないように見える ユーティリティメソッドを使用できるという追加の利点があります。

欠点は、偽の名前空間の外部で非プライベートクラスを使用するには、Foo内でそれらを参照する必要があることです。

using MyCompany;

// ...

var baz = new Foo.Baz();

これは、クラスのエイリアスを使用することで軽減できます。

using Baz = MyCompany.Foo.Baz;

// ...

var baz = new Baz();

ただし、使用する非プライベートクラスごとに実行する必要があります。

[〜#〜]更新[〜#〜]

C#6には static usingステートメント が含まれることに注意してください。これにより、public static partial classを「モジュール」として使用するというこの提案を効果的に改善できます。 「モジュール」を「使用」して、そのタイプに直接アクセスします。

うまくいけば、それは次のように機能します:

using MyCompany.Foo;

// ...

var baz = new Baz();

Fooが名前空間であるかのように。

15
Jordão

クラスを名前空間に対してプライベートにすることを許可しても、意味のあるレベルの保護は実現されません。

世界中のどのアセンブリも、単にdllを参照し、おそらくプライベートクラスにアクセスする名前空間にコードを書き始めることができます。

それがおそらくマイクロソフトから得られる答えだと思います。

21
Alex Humphrey

別のタイプのメンバーとして、プライベートクラスを作成できます。

public class Outer {
  // ...
  private class Inner {
    // ...
  }
}

InnerOuterのメンバーにのみ表示されます。

最も外側のレベル(つまり、名前空間内)では、その定義に従ってprivateは意味がありません(プライベートにするものがないため)。代わりに、internalを使用してください(含まれているアセンブリのメンバーにのみ表示されます)。

11
Richard

プライベートクラスを定義できますが、それを含むクラスでのみ使用できます。

特定のアセンブリ(DLL/EXEなど)内でのみ表示されるクラスが必要な場合は、それをinternal(VBではFriend)として宣言する必要があります。

2
Rowland Shaw

だから私はあなたがこれをしたいと思います

namespace Baz
{
    private class foo
    {
        private int _bar;
    }
}

もし、そうなら。次に、fooがサーバーする目的は何ですか。名前空間では、内部よりも制限を厳しくして、クラスを使用できます。これを実行できる場合は、どこでこれを使用しますか。

これが、このコンパイル時の検証がある理由です。

現在、パブリッククラス内にプライベートクラスを設けることは理にかなっています。これをうまく説明することはできません C#のプライベート内部クラス-なぜそれらはより頻繁に使用されないのですか?

1
Ash

本当ですが、名前空間が複数のアセンブリに分割されている場合は、内部クラスと internalsvisibletoAttribute を使用してこれをかなり厳密にシミュレーションできます。

また、別のクラス内のクラスを外部クラスに対してプライベートにすることができることにも注意してください。外部クラスは、この目的のための名前空間と見なすことができます。

1
Preet Sangha