3

MainSubという 2 つのアセンブリがあり、SubはMainに依存しています。Mainは、 Subでオーバーライドしたいメンバーを持ついくつかのクラスを定義します。これらのメンバーを としてオーバーライドします。protected internal virtualprotected override

Mainには無関係なクラスがあり、それをMain.Sharedと呼びます。これをSubで使用したいのですが、他のアセンブリにそれを見せたくありません。状況は次のとおりです。

//In assembly Main:
public class Shared
{
}
public class Parent
{
    protected internal virtual void DoStuff()
    {

    }
}
//In assembly Sub:
public class Child : Parent
{
    protected override void DoStuff()
    {
        base.DoStuff();
    }
} 

InternalsVisibleToそのため、通常どおり属性を使用しました。ただし、 Mainをこの属性で装飾した後、コードはコンパイルを拒否します。エラー メッセージには、おそらくMainSubが同じアセンブリであると考えられるため、 DoStuffasをオーバーライドする必要があることが示されています (?)protected internal override

すべてのオーバーライドを手動で保護された内部に変更する必要があり、それらの多くがあるため、これは大きな問題です。さらに、後で属性を削除したい場合があり、すべてを元に戻す必要があります。

これを避ける方法はありますか?(コードベースの完全な再設計に加えて...)

また、なぜこれが起こるのかについても興味があります。この動作は単なる盲点ですか、それともこのように機能するはずですか?

4

1 に答える 1

4

さて、私は今それを理解していると思います。C# の仕様ではこれについて言及されていませんが、実際にはまったく言及InternalsVisibleToされていません。それを理解する方法は、メンバーの許容可能な呼び出しサイトのセットをオーバーライドして変更できないことだと思います。

他のすべてのアクセシビリティ修飾子については、同じ修飾子に固執する必要があることを意味しますが、protected internalわずかに異なります。がなければInternalsVisibleTo、元のアセンブリ内およびサブクラス内でアクセスできます (protected正確に簡潔に記述するのが少し難しい の通常の規則に従います)。別のアセンブリでそれをオーバーライドする場合、通常は、「新しい」アセンブリではなく、サブクラスと元のprotectedアセンブリでのみ使用できるようにする必要があります。

しかし、ここInternalsVisibleToで考えてみると、2 番目のアセンブリ内のすべてのコードが既にメンバーにアクセスできるため、アクセシビリティprotected低下します。したがって、それを維持するために保持する必要があります。(2 番目のアセンブリは、その内部を元のアセンブリに表示する必要はありません。元のアセンブリは 2 番目のアセンブリを参照できないため、循環参照が発生するためです。)protected internal

ただし、それでもアクセス可能性が向上する可能性があるため、内部がアセンブリ B に表示されるアセンブリ A と、内部がアセンブリ C に表示されるアセンブリ B がある場合、アセンブリ A のprotected internalメソッドは両方のアセンブリ A に表示される必要があります。そしてB; ただし、アセンブリ C でオーバーライドすると、アセンブリ B と C、またはサブクラスに対してのみ可視にすることができます。この時点で、本当に「アセンブリ A とそれが信頼するアセンブリ」に見えるようにしたいのですが、それを表現する方法はありません。

わかる?

于 2013-12-02T20:29:55.323 に答える