6

ServerIRC のサーバー接続と通信するクラスがあります。既知の のリストを保持し、User必要に応じてそれらを作成します。

Userクラスに関連する2つの問題があります。

  1. のインスタンスは誰でも作成できますUserServerクラスでこれができるようにしたいだけです。
  2. ユーザー (User記述されているもの) が自分の名前 (または参加しているチャンネルなどのその他の情報) を変更した場合、Serverクラスはそれ自体を変更できます。ただし、他のクラスも可能です。他のクラスがこの情報に触れることを禁止したい (読み取り専用にする)。

この2つの問題を解決するにはどうすればよいですか?C++ では、friendキーワードを使用して ctorsetNameなどを非公開にすることで解決できます。

特定のメソッドが指定されたクラスからアクセスできるようにする C# キーワードはありますか? これで私の問題は解決します。

4

3 に答える 3

8

正直なところfriend、C++ から発生したアクセスは、設計が悪いことを示していると思います。デザインを修正した方がよいでしょう。

まず、誰かがユーザーを作成したかどうかを本当に気にする人はいますか? それは本当に問題ですか?私がこれを尋ねるのは、私たちプログラマーが、単に起こらないこと、または起こったとしても問題にならないことについて心配することがあるように思われるからです。

本当に気にする場合は、次のいずれかを実行します。

  • ユーザーをインターフェイスにします。サーバーは、それを実装するプライベート クラスをインスタンス化できます。また
  • User をパブリック コンストラクターのない Server の内部クラスにして、Server だけがインスタンス化できるようにします。

可視性のハック (C++ の友人がその 1 つであり、Java のパッケージ アクセスはどちらも良い例です) は単にトラブルを求めているだけで、良い考えではありません。

于 2009-02-15T03:54:37.657 に答える
5

.NET の世界で最も近いのfriendinternal可視性です。

2 つのクラスが別々のアセンブリにある場合は、InternalsVisibleTo属性を使用して、一方のアセンブリが他方のアセンブリの内部を表示できるようにすることができます。

于 2009-02-15T03:42:48.450 に答える
1

クラス階層を再設計することは、おそらくこの問題に対する公正な解決策です。Server クラスの外部に存在する場合、本当に必要なのは読み取り専用の User クラスだと思われるからです。

私はおそらく次のようなことをするでしょう:

// An abstract base class. This is what I'd use outside the 
// Server class. It's abstract, so it can't be instantiated
// on its own, and it only has getters for the properties. 
public abstract class User
{
   protected User()
   {
   }

   public string Name { get;}
   // Other get-only properties
}

public class ServerUser : User
{
   public ServerUser()
   {
   }

   public string Name { get; set;}
   // Other properties. 
}

次に、Server クラスで ServerUser クラスを作成し、Server クラスを使用して ServerUser クラスのプロパティを変更しますが (ユーザー名の変更など)、User クラスを外部に公開するだけです。

于 2009-02-15T03:53:24.387 に答える