50

抽象基本クラスを持つ共通のアセンブリ/プロジェクトがあり、次にいくつかの派生クラスを他のアセンブリに公開したいと考えています。

抽象基本クラスが Intellisense のこれらの他のアセンブリに表示されないようにしたいのでinternal、作成すると思ったのですが、次のエラーが発生します。

一貫性のないアクセシビリティ: 基本クラス 'Settings' は、クラス 'IrcSettings' よりもアクセスしにくくなっています ....

よくわかりません。私は抽象Settingsクラスを作成することを余儀なくされているため、publicこのアセンブリの外に表示されます。

internal代わりにこのクラスを作成するにはどうすればよいですか?

4

7 に答える 7

98

私が理解しているように、抽象クラスを同じアセンブリ内の他のクラスによってのみ実装する必要があります (たとえば、内部です) が、派生クラスはパブリックにすることができます。

これを行う方法は、抽象基本クラスをパブリックにすることですが、内部のデフォルト コンストラクターを与えます。

public abstract class MyClass
{
    internal MyClass() { }
}

これにより、MyClass (およびそのメンバー) がアセンブリ外のクラスに表示され、使用できるようになりますが、アセンブリ外のクラスはそれから継承できません (コンパイル エラーが発生します)。

編集:外部アセンブリによって表示されるクラスが MyClass から継承されている場合、MyClass も表示されないようにすることはできませんたとえば、Intellisense に表示されます。ただし、上記に従うことで、それらの使用を防ぐことができます。

于 2009-08-07T14:16:56.380 に答える
10

クラスの継承階層全体が可視である必要があるため、抽象基本クラスはパブリックである必要があります。これにより、ポリモーフィズムが機能し、有効であることが保証されます。ただし、すべての基本クラスのメンバーは内部 (コンストラクターを含む) である可能性があるため、アセンブリの外部では使用できません

于 2009-08-07T14:16:12.823 に答える
8

達成しようとしていることに大きなメリットはありませんが、実際に達成しようとしていることはこれに似ています。

すべてが内部の 1 つのアセンブリに抽象基本クラスを配置します。そのアセンブリの AssemblyInfo に追加する必要があります

[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]

次に、別のアセンブリで、公開したいすべてのクラスを取得します。cs_friend_assemblies_2 内の任意のコードまたはアセンブリに名前を付けたものについては、Intellisense から基本クラスに引き続きアクセスできますが、それ以外の場所にはアクセスできないことに注意してください。

于 2009-08-07T14:19:51.977 に答える
5

クラスを継承のために他のアセンブリで同時に使用できるようにすることはできませんが、プライベートにすることもできるため、他のコンシューマーには表示されません。クラスを内部化し、属性を使用して特定のアセンブリ (フレンド アセンブリの場合) に公開すること[InternalsVisibleTo]はできますが、これはあなたが望むものではないと思います。

コード (派生クラス以外) が基本クラスをインスタンス化できないようにする場合は、保護されたコンストラクターを与えることができます。

abstract class MyBaseClass
{
    protected MyBaseClass() { ... } // only inheritors can access this...
}

EditorBrowsable次の属性を使用して、Intellisense からクラス メンバーを非表示にできます。

abstract class MyBaseClass
{ 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public void SomeMethodToBeHidden() { }
}

IDE が常にこの属性を尊重しないという問題が報告されていることに注意してください。

于 2009-08-07T14:21:08.713 に答える
1

私に関する限り、これは問題ではありません。観察:

public abstract class Foo {
    public void virtual Bar() {
        // default implementation
    }
}

public class NormalFoo : Foo { }

public class SpecialFoo : Foo {
    public override void Bar() {
        // special implementation
    }
}

var foolist = new List<Foo>();

foolist.Add( new NormalFoo() );
foolist.Add( new SpecialFoo() );

foreach (var f in foolist) {
    f.Bar();
}

上記は、ポリモーフィズムがなければまったく機能しません。つまり、共通のインターフェイスである抽象基本クラスを介してさまざまな派生クラスのインスタンスを参照できます。あなたがしたいことは、それを取り除き、クラス階層の使いやすさを損なうことです。この道を進むべきではないと思います。

于 2009-08-07T17:48:28.040 に答える
0

他のアセンブリは、抽象基本クラスから継承するか、または抽象基本クラスから継承するパブリック クラスのいずれかを継承しますか?

その場合は、抽象基本クラスを公開する必要があります。アセンブリ内部の外部に表示したくないメソッドを作成するだけです。

そうでない場合、インターフェイスが役立つ可能性がありますか? パブリック インターフェイスを定義し、パブリック クラスにそれらを実装させ、インスタンスを取得するためのファクトリを提供します。そうすれば、インテリセンスがアセンブリの外側で見るのはインターフェイスだけです。

それは役に立ちますか?

于 2009-08-07T14:32:07.230 に答える