web-dev-qa-db-ja.com

「プライベート」と「保護された内部」の違いは何ですか?

実際の違いは何か知りたいだけです 民間 そして 保護された内部 アクセス指定子。私の知る限り

自分のクラスメンバーに表示: プライベートで保護された内部[〜#〜] yes [〜#〜]

他のクラスのオブジェクトに表示: 両方[〜#〜] no [〜#〜]

名前空間コレクション外の他のクラスのオブジェクトに表示されます: 両方[〜#〜] no [〜#〜]

名前空間コレクション外の子クラスのオブジェクトに表示されます: 両方[〜#〜] no [〜#〜]

privateprotected internalと同じことをしている場合、なぜ両方が必要なのか、どちらか一方だけで十分かどうか。

14
avirk
  • A protected internalメンバーは、現在のアセンブリまたはの任意のコードから別のアセンブリの派生クラスに表示されます。技術的に言えば、それはprotectedinternalの-​​ 論理和 です。
  • privateメンバーは、同じクラスのコードにのみ表示されます。

protected internalは、実際にはpublicに次いで2番目に許容度の高いアクセス修飾子です。


protectedは間違いなくmoreinternalよりも寛容であることに注意してください。これは、制御できないコード(つまり、他のアセンブリ)からのアクセスを許可するためです。 internalは現在のアセンブリのallコードからのアクセスを許可しますが、このコードはあなたのものであり、あなたがそれを制御できます!

言い換えると、protected(およびprotected internal)メンバーはアセンブリのパブリックAPIの一部です(したがって、文書化する必要があります)。 internalメンバーはそうではありません。

26
Will Vousden

グラフィカルな概要(一言で言えば要約)

Visibility

24
Stefan Steiger

プライベート

タイプまたはメンバーには、同じクラスまたは構造体のコードでのみアクセスできます。

保護された内部

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

3
techno

保護された内部とは、同じアセンブリを継承し、同じアセンブリ内にあるクラスのみがそのプロパティを表示できることを意味すると思います。クラスを派生し、異なるアセンブリからのものは、それを見ることができません。

LE:これについてのMattiasBuelensのコメントを読んでください。

0
Andrei Neagu

さまざまなフォーラムやブログで提供されている説明を読んで、保護された内部と.NETコンテキストの内部の違いを理解しようとしていました。私は本当に理解できなかったので、VS2015を使用して2つの別々のアセンブリを作成しました。おそらく今、私は基本的な理解を持っています。私はあなたと共有したいと思います、それは誰かに役立つかもしれません。あるアセンブリで宣言されたフィールドを別のアセンブリから使用しようとしました。また、別のアセンブリで宣言されたクラスから派生してみました。アセンブリ1のclass1.csのコードは次のとおりです

namespace Z_Dll_1
{
    public class PublicBaseClassAssemblyOne
    {
        internal int _myinternal = 200;
        protected internal int _protectedinternal = 100;
        protected int _myProtected = 123;
        private int _myPrivate = 2;
        public int _myPublic = 45;
    }

    public class DerivedClassAssemblyOne : PublicBaseClassAssemblyOne
    {
        protected internal int intM = 10;
    }

    internal class MyInternalClass
    {
        public void MyMethod()
        {
            Console.WriteLine("Method one with internal class");
            PublicBaseClassAssemblyOne cl1 = new PublicBaseClassAssemblyOne();
            cl1._myinternal = 1000; //Internal type is available since it is in same Assembly
            cl1._protectedinternal = 10; // protected internal is available
            cl1._myPublic = 2;  // Public OK
            //cl1.myPrivate = ?? // nor available since it is private

            DerivedClassAssemblyOne drOne = new DerivedClassAssemblyOne();
            drOne._myinternal = 30; // Internal and available from derived class
            drOne._myPublic = 1; // Public 
            drOne._protectedinternal = 2; // Able to be accessed from same Assembly or derived class from other Assembly
        }
    }
}

これは、Z_Dll_1を使用した別のアセンブリclass2.csのコードです。

namespace Z_Dll_2
{
    public class ClassAssembly2
    {
        public ClassAssembly2()
        {
            PublicBaseClassAssemblyOne classfromOtherAssembly = new PublicBaseClassAssemblyOne();
            classfromOtherAssembly._myPublic = 0; //Only public is available
        }
    }

    public class ClassDerivedFromOtherAssemblyClass : PublicBaseClassAssemblyOne
    {
        public ClassDerivedFromOtherAssemblyClass()
        {
        }
        void ClassDerivedFromOtherAssemblyClassTestMethod()
        {
            //_myinternal = 200; // can't access since it was internal to other Assembly
            _protectedinternal = 100; // this can be accessed as it is  derived class from other class that has protected internal 
            _myProtected = 123; // Ordinary protected data accessed from derived class
            //_myPrivate = 2; //Private member can't be accessed from  derived class
            _myPublic = 45; // Public can be accessed anyway

            //Try to create an instance of internal class
            //MyInternalClass intClass = new MyInternalClass(); //Not accessible from this Assembly
        }
    }
}
0
RotatingWheel

実際には、私は通常、変数にprivateを使用して、他のクラスによって誤用されないようにします。

内部で保護されていますが、他のほとんどのクラスでは使用できないが、テストケースを作成するためにアクセスできるようにしたいメソッドによく使用します。テストクラスを適切な名前空間またはパッケージ構造で作成して、保護された内部メソッドに不適切に公開することなくアクセスできるという点で非常に便利です。

このアプローチには、簡単に「テスト可能な」コードを書くことが優先されるコーディングへのアプローチが必要です。これが私のアプローチではなかった場合、保護された内部を使用する機会がたくさんあるかどうかはわかりません。

0
Geoff