web-dev-qa-db-ja.com

C#では、public、private、protected、およびaccess modifierを持たないことの違いは何ですか?

publicを使用してきたすべての大学時代、publicprivate、およびprotectedの違いを知りたいですか。

また、staticは何も持たないのとは対照的に何をするのでしょうか。

678
MrM

アクセス修飾子

docs.Microsoft.com から

一般公開

型またはメンバーは、同じアセンブリ内の他のコード、またはそれを参照する別のアセンブリからアクセスできます。

プライベート

型またはメンバは、同じクラスまたは構造体内のコードによってのみアクセスできます。

保護された

型またはメンバは、同じクラスまたは構造体、あるいは派生クラス内のコードによってのみアクセスできます。

private protected (C#7.2で追加)

型またはメンバは、同じクラスまたは構造体、あるいは同じアセンブリから派生クラスにあるコードによってのみアクセスできますが、別のアセンブリからはアクセスできません。

内部

型またはメンバーは、同じアセンブリ内の任意のコードからアクセスできますが、別のアセンブリからはアクセスできません。

保護された内部

型またはメンバは、同じアセンブリ内の任意のコード、または別のアセンブリ内の任意の派生クラスからアクセスできます。

アクセス修飾子なし が設定されている場合は、デフォルトのアクセス修飾子が使用されます。そのため、設定されていなくても常に何らかの形のアクセス修飾子があります。

静的

クラスの静的修飾子は、そのクラスをインスタンス化できないこと、およびそのすべてのメンバーが静的であることを意味します。静的メンバーは、それを囲む型のインスタンスがいくつ作成されるかにかかわらず、1つのバージョンを持ちます。

静的クラスは基本的に非静的クラスと同じですが、違いが1つあります。静的クラスは外部的にインスタンス化することはできません。つまり、newキーワードを使用してクラス型の変数を作成することはできません。インスタンス変数がないため、クラス名自体を使用して静的クラスのメンバーにアクセスします。

しかし、 静的コンストラクタ のようなものがあります。静的クラスを含め、どのクラスでもこれらのいずれかを持つことができます。直接呼び出すことはできません。また、パラメータを持つことはできません(クラス自体の型パラメータ以外)。最初のインスタンスが作成される前、または静的メンバーが参照される前に、静的コンストラクターが自動的に呼び出されてクラスを初期化します。こんな感じです:

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}

静的クラスはしばしばサービスとして使われます、あなたはそのように使うことができます:

MyStaticClass.ServiceMethod(...);
951
mbillard

Public - あなたがクラスを見ることができれば、あなたはメソッドを見ることができます

Private - あなたが クラスの の一部であるなら、あなたはそのメソッドを見ることができます。

Protected - Privateと同じで、すべての 子孫 もこのメソッドを見ることができます。

静的(クラス) - "クラス"と "オブジェクト"の違いを覚えていますか?それをすべて忘れなさい。それらは "static"と同じです。クラスはそれ自身の唯一のインスタンスです。

Static(method) - このメソッドを使うときはいつでも、それが属しているクラスの実際のインスタンスから独立した参照フレームを持つことになります。

154
JosephStyons

グラフィカルな概観(要約)

Visibility

アクセス修飾子を前面に付けない場合のデフォルトについては、こちらを参照してください。
C#のクラスとメンバー(フィールド、メソッドなど)のデフォルトの可視性

入れ子になっていない

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

入れ子:

nested enum      public
nested interface public
nested class     private
nested struct    private
143
Stefan Steiger

なし の質問について

  • 名前空間タイプはデフォルトで内部的です
  • 入れ子型を含むすべての型メンバーは、デフォルトではプライベートです。
22
leppie

enter image description here

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}
19
Narottam Goyal

この回答 から素晴らしい図を再投稿します。

以下は、より限定的なものから無差別的なものまで、ベン図のすべてのアクセス修飾子です。

private
enter image description here

private protected: - C#7.2で追加
enter image description here

internal
enter image description here

protected
enter image description here

protected internal
enter image description here

public
enter image description here

15
Paul

うーん。

ここを見てください: アクセス修飾子

手短に:

Publicは、メソッドまたは型に他の型/クラスからの完全な可視性を与えます。

Privateは、privateメソッド/変数を含む型のみが、プライベートメソッド/変数へのアクセスを許可します(入れ子になったクラスも、包含クラスのプライベートメソッド/変数へのアクセス権を持つことに注意してください)。

派生クラスも保護されたメソッドにアクセスできることを除けば、protectedはprivateに似ています。

"Nothing"はVB.NETのnullと同等のものです。 「何もしない」という意味で「アクセス修飾子がない」というのであれば、それは左右されます。宣言は通常、 制限付き のようになります。すなわち.

public class MyClass
{
    string s = "";
}

は実質的に同じです。

public class MyClass
{
    private string s = "";
}

明示的に指定されたアクセス修飾子がない場合は、リンクされたMSDNの記事で詳細な説明が提供されます。

11
CraigTP

public - はどこからでも誰でもアクセスできます。
[ - 。] private - はその一部であるクラス内からのみアクセスできます。
[ - 。] protected - は、クラス内、またはクラスから継承したオブジェクトからのみアクセスできます。

何もnullに似ていますが、VBにはありません。
静的とは、そのオブジェクトの1つのインスタンス、そのクラスのすべてのインスタンスに対してmethodがあることを意味します。

8
Tony

現在の アクセス修飾子のさらに別の視覚的アプローチ (C#7.2)。うまくいけば、スキーマがそれを簡単に覚えておくのに役立ちます
(インタラクティブビューの画像をクリックしてください。)

interactive access modifiers svg

外の中

2つの単語を含むアクセス修飾子を覚えていない場合は、outside-insideを覚えておいてください。

  • 非公開保護 非公開 外側(同じアセンブリ) 保護 内側(同じアセンブリ)
  • 保護された内部 保護された 外部(同じアセンブリ) 内部 内部(同じアセンブリ)
4
user1810087

Privateのステータスは、変数が同じクラスのオブジェクトによってのみアクセスできることを示します。保護されたステータスはそのアクセスをクラスの子孫も含むように拡張します。

「上の表から、privateとprotectedの違いがわかります。どちらも同じだと思います。そのため、この2つの別々のコマンドの必要性は何です。」

詳細については、 _ msdn _ linkを確認してください。

4
Grant Hood

うーん...

静的とは、クラスのインスタンスがなくてもその関数にアクセスできることを意味します。

あなたはクラス定義から直接アクセスすることができます。

4
gbianchi

あなたのクラスのあなたのアクセシビリティを注意深く見てください。パブリッククラスおよび保護されたクラスとメソッドは、デフォルトですべての人がアクセスできます。

またMicrosoftは、Visual Studioで新しいクラスが作成されたときにアクセス修飾子(public、protectedなどのキーワード)を表示することについてはあまり厳密ではありません。だから、それはあなたの実装内部への扉であるので、慎重にあなたのクラスのあなたのアクセシビリティについて考えてください。

3
Patrick Peters

これらのアクセス修飾子はあなたのメンバーが見える場所を指定します。あなたはおそらくこれを読むべきです。出発点としてIainMHによって与えられたリンクを取りなさい。

静的メンバーはクラスごとに1つで、インスタンスごとに1つではありません。

3
jpfollenius

私はそれが良いOOPデザインに関連していると思います。あなたが図書館の開発者であるならば、あなたはあなたの図書館の内部の働きを隠したいです。そうすれば、後でライブラリの内部動作を変更できます。そのため、あなたはあなたのメンバーとヘルパーメソッドを非公開にし、インターフェースメソッドだけが公開されます。上書きされるべきメソッドは保護されるべきです。

2

C#には全部で 6 アクセス修飾子があります。

private :このアクセシビリティを使用して宣言されたメンバは、包含型内に表示できます。派生型、同じアセンブリ内の他の型、または包含アセンブリ外の型には表示されません。つまり、アクセスは包含型のみに制限されます。

protected :このアクセシビリティを使用して宣言されたメンバは、収容アセンブリ内の収容タイプから派生した型と、収容アセンブリ外の収容型から派生した型の中に表示できます。つまり、アクセスは包含型の派生型に制限されます。

internal :このアクセシビリティを使用して宣言されたメンバは、このメンバを含むアセンブリ内に表示できますが、それを含むアセンブリ以外のアセンブリには表示されません。つまり、アクセスはアセンブリのみを含むように制限されます。

内部保護 :このアクセシビリティを使用して宣言されたメンバは、収容アセンブリの内部または外部の収容タイプから派生した型の中に表示できます。また、収容アセンブリ内のすべての型にも表示できます。つまり、アクセスはアセンブリまたは派生型を含むことに限定されます。

public :このアクセシビリティを使用して宣言されたメンバは、このメンバを含むアセンブリ、またはそれを含むアセンブリを参照する他のアセンブリの中に表示することができます。すなわち、アクセスは制限されない。

C#7.2では、新しいレベルのアクセシビリティが追加されています。

private protected :このアクセシビリティで宣言されたメンバは、それを含んでいるアセンブリ内のこの包含型から派生した型の中から見ることができます。収容型から派生していない型、または収容アセンブリの外側にある型には表示されません。すなわち、アクセスはそれを含むアセンブリ内の派生型に制限されます。

新しい個人用保護されたアクセス修飾子のサンプルコードを含むソース

1
Baccata