4

アクセス修飾子のない型のこのプロパティ(つまり、internalアクセス):

class SomeType {
    private int length;
    internal int Length {
        get { return length; }
        set length = value; }
    }
}

SomeType のアセンブリ内のすべての型とアクセサーを使用できるようgetにしsetます。問題: アクセスをSomeType (および実際の SomeType) から派生した型のみに制限するにはどうすればsetよいですか?

internal int Length {
    get { return length; }
    protected set length = value; }
}

はコンパイラによって拒否されます。これは、protectedよりも制限が緩いと言われているためですinternal(おそらく:protectedとの交差がありますが、完全に含まれてinternalいるわけではありません--> 派生型は の範囲を超えて存在できます)。internalinternal

アセンブリ内の任意の型からアクセスされ、アセンブリ内の派生型によってのみ設定されるコードは何でしょうか?

編集: 回答を確認した後、解決策に違いが生じる可能性があるため、プロパティの別の特性を追加する必要があると思います: プロパティのタイプは実際にはSomeTypeです。編集されたコードは次のとおりです。

class SomeType {
    private SomeType length;
    internal SomeType Length {
        get { return length; }
        set length = value; }
    }
}

プロパティが宣言されている場合public、コンパイラはエラーを発行します (プロパティ タイプ SomeType は、プロパティ Length よりもアクセスしにくくなります)。

4

3 に答える 3

5

(編集:確認したところ、これはプロパティの型が宣言型と同じ場合でも機能します。ただし、型がパブリック型内でプロパティを宣言しようとしている場合は機能しませんプロパティのは内部型です。)

C# では (厳密に言えば) これを行うことはできませんが、非常によく似たことができます。

protected internal int Length { get; protected set; }

(簡単にするために、これは自動的に実装されたプロパティを使用しています。同じ手法が「通常の」プロパティでも機能します。)

これにより、同じアセンブリおよび派生型内の任意の型から "getter" にアクセスできるようになります。「セッター」は派生型にのみアクセスできます。とにかくあなたのクラスは内部であるため、これはとにかくかなり同等です-ゲッターは理論的にはアセンブリの外部の型にアクセスできますが、クラスは内部であるため、別のアセンブリからは何も派生してはなりません。

問題は、プロパティでは、1 つのアクセス レベルが他のアクセス レベルの「サブセット」である必要があることです。internalそのようには機能しprotectedません-1つの型が同じアセンブリにある可能性がありますが、問題の型から派生することはできません。それから別の型を派生させることはできますが、別のアセンブリ内にあります。基本的に、それらは直交しています。

上記のソリューションは、同じアセンブリ内または型から派生したprotected internal任意の型にアクセスできることを意味するため、機能します。明らかに、それぞれと個別にこれのサブセットです。protectedinternal

C# に CLR の「ファミリとアセンブリ」アクセス レベルに相当するものがある場合、セッターに対してさらに制限されたプロパティを作成できます。(は「ファミリまたはアセンブリ」と同等です。) 残念ながら、そうではありません :(internalprotected internal

最初に述べた目標が本当に必要な場合(たとえば、後で同じ制限を適用したい public クラスがある場合)、代わりにそれらの少なくとも 1 つを別のメソッドにする必要があります。

private int length;
internal int Length { get { return length; } }

protected void SetLength(int value)
{
    this.length = value;
}
于 2010-01-17T14:24:07.703 に答える
3

クラス自体は宣言アセンブリでのみ表示されるため (暗黙的internalなアクセス修飾子により)、プロパティpublicとセッターでgetter を作成するだけprotectedです。

class SomeType {
    private int length;

    public int Length {
        get { return length; }
        protected set { length = value; }
    }
}

クラス自体が表示されないため、ゲッターアセンブリの外からアクセスできません。


トピック外: 最近の C# コンパイラを使用している場合は、代わりに自動プロパティを使用することをお勧めします。

class SomeType {
    public int Length { get; protected set; }
}

これは言語/コンパイラのトリックにすぎないため、使用するためにバージョン 3.X フレームワークに対してコンパイルする必要はありません。

于 2010-01-17T14:31:12.133 に答える
-1

向きを変えることはできませんか(テストしていません):

protected int Length
{
    internal get { return length; }
    set { length = value; }
}
于 2010-01-17T14:21:56.253 に答える