0

私が定義しているパブリック クラスは最終的に API の一部になるため、特定のパブリック プロパティが必要です。ただし、自分のプロジェクト内から作成されたものでない限り、一部のプロパティを読み取り専用にしたい (たとえば、ユーザーが API を持っている場合、ユーザー オブジェクトを作成できますが、その ID に書き込むことはできません)。データベースから取得した場合にのみ入力されます)。

私の考えでは、同じ名前空間、「パブリック」DLL と「プライベート」DLL を使用する 2 つの別個のアセンブリを用意することでした。パブリック DLL のプロトタイプは次のようになります。

namespace CompanyName
{
  public partial class User
  {
    public Id { get; }
    public Name { get; set; }
  }
}

プライベート DLL は次のようになります。

namespace CompanyName
{
  public partial class User
  {
    public Id { set; }
  }
}

これは機能しますか?そうでない場合、これを行うためのより良い方法は何ですか?

4

5 に答える 5

9

部分クラスは複数のアセンブリにまたがることができないため、これは機能しません。

クラスを次のように定義できます。

namespace CompanyName
{
    public class User
    {
        public Id {get;internal set;}
        public Name {get;set;}
    }
}

これは、クラスへの内部アクセスを持つコードのみがプロパティの値を設定できることを意味しIdます。アセンブリの外部から設定する必要がある場合は、アセンブリに厳密な名前が付けられていることを確認してから、InternalsVisibleTo属性を使用して、アセンブリへの内部アクセスを別のアセンブリ ( の値を設定するものId) に与えることができます。


私は最近、私が取り組んでいる API に対して、これと非常によく似たことをしなければなりませんでした。私たちの API は主にインターフェイスを使用して定義されているため、パブリック部分であるパブリック API プロジェクトと、内部コードで使用される API を形成する内部 API プロジェクトを用意することでこれを実現できました。内部インターフェイスはパブリックのものから派生しています。 . API インターフェースの実装は両方のインターフェースを実装します。つまり、内部コードは公開されていない API の部分にアクセスできます。

于 2009-12-11T23:06:06.473 に答える
5

いいえ、これはうまくいきません。部分クラスはコンパイル時にマージされます。コンパイルされたクラスにメンバーを追加することはできません。

コードがどのようにレイアウトされているかに応じて、内部セッターを提供することをお勧めします。

public int Id { get; internal set; }

別のアセンブリからセットを実行できるようにする必要があるが、制御するアセンブリは 1 つだけである場合は、InternalsVisibleToAttribute を使用して、そのアセンブリに内部セッターへのアクセスを許可できます。

于 2009-12-11T23:08:00.463 に答える
2

これがうまくいくとは思えません。部分クラスは一緒に同じアセンブリにコンパイルされ、CLR によって処理されないと思います。internalキーワードを表示したい場合があります。

たぶん、このようなことをします

abstract internal class UserPrototype
{
    protected Property....
}


sealed class User : UserPrototype
{
    public ...
}
于 2009-12-11T23:07:17.053 に答える
0

API を設計する際の秘訣は、インターフェイスのカテゴリ (この場合は抽象クラス) で考えることです。このコードを見てください:

public abstract class User
{
    protected String _name;
}

public sealed class PublicUser : User
{
    public String Name
    {
        get{ return this._name; }
    }
}

public class PrivateUser : User
{
    public String Name
    {
        get { return this._name; }
        set { this._name = value; }
    }
}

明らかに、任意のクラス/名前空間名を使用できます。これは、物事を明確にするためだけです。ご覧のとおり、すべてのクラスは公開されているため、クライアントでどの DLL を使用できるかはユーザー次第です。

于 2009-12-12T00:31:03.430 に答える