13

私たちのビジネスモデルには学生クラスがあります。ある学生を別の学生から操作している場合、学生のプライベートメンバーが表示されます。これはなぜですか?

   class Program {
      static void Main(string[] args) {

         Student s1 = new Student();
         Student s2 = new Student();

         s1.SeePrivatePropertiesAndFields(s2);
      }
   }

   public class Student {

      private String _studentsPrivateField;

      public Student() {
         _studentsPrivateField = DateTime.Now.Ticks.ToString();
      }

      public void SeePrivatePropertiesAndFields(Student anotherStudent) {
         //this seems like these should be private, even from the same class as it is a different instantiation
         Console.WriteLine(anotherStudent._studentsPrivateField);
      }
   }

これの設計上の考慮事項/意味について考えてもらえますか。兄弟から情報を隠すことはできないようです。フィールドまたはメンバーを同じクラスの他のインスタンスから非表示としてマークする方法はありますか?

4

11 に答える 11

9

これを確実にする簡単な方法があります。

同じクラスの他のインスタンスのプライベート メンバーをいじらないでください。

Student真剣に -コードを書いているのはあなたです。

于 2010-01-19T00:43:40.263 に答える
8

これを確実にする最も簡単な方法は、次のようなインターフェイスにプログラムすることです。

class Program
{
    static void Main(string[] args)
    {
        IStudent s1 = new Student();
        IStudent s2 = new Student();

        s1.ExamineStudentsMembers(s1);
    }
}

public interface IStudent
{
    void ExamineStudentsMembers(IStudent anotherStudent);
}

public class Student : IStudent
{
    private string _studentsPrivateMember;

    public Student()
    {
        _studentsPrivateMember = DateTime.Now.Ticks.ToString();
    }

    public void ExamineStudentsMembers(IStudent anotherStudent)
    {
        Console.WriteLine(anotherStudent._studentsPrivateMember);
    }
}

ExamineStudentsMembers がプライベート フィールドにアクセスしようとしているため、これはコンパイルされなくなります。

于 2010-01-19T00:54:04.123 に答える
6

クラスを作成している場合は、それを完全に制御できます。そのため、あるオブジェクトが別のオブジェクトを変更できないようにする場合は、その機能を記述しないでください。

クラスは、他のインスタンスでプライベート変数を使用して、効率的な比較およびコピー機能を実装することがよくあります。

于 2010-01-19T00:49:46.333 に答える
4
  • Private は、メンバー (フィールド/メソッド/など) が親 type のコード内からのみアクセスできることを意味します。CSharpOnlineから
  • 複数のインスタンスのプライベート メンバーが表示され、呼び出すことができます。これは、引数が同じ型のインスタンスである型に「コピー コンストラクター」または「クローン」メソッドを実装する場合に便利です。設計者がプライベート フィールドにアクセスできないようにしている場合は、それらを取得するためにクローン/コピーのためだけに多数のゲッター メソッドを作成する必要がある場合があります。私見、私はそのままの方が好きです。同じタイプ内では、別のオブジェクトの状態を読み取ることは、それに書き込むことほど悪くはありません (これは、あなた/あなたのチームにとって DONT-code-convention になる可能性があります)。
于 2010-01-19T01:03:37.550 に答える
2

私は2番目のポイントが好きです、あなたは見ることができますが、それらのプライベートメンバーに触れないでください。

おかしなことに、私は一度先生を知っていましたが、彼はメンバーを見て大丈夫なクラスと実際に遊ぶことができるクラスを決めるのにしばしば問題があると言いました。

于 2010-01-19T11:51:47.027 に答える
2

次のように表現すると、兄弟のプライベートデータへのアクセスが間違っているように見える場合があります。

public void ExamineStudentsMembers(Student anotherStudent) {
    //this seems very wrong
    Console.WriteLine(anotherStudent._studentsPrivateMember);
}

ただし、この種の機能を必要とするメソッドにとってはそれほど奇妙なことではないようです。兄弟のプライベートデータにアクセスするために必要な方法は何ですか?比較メソッド(特に等しい)とデータ構造内のオブジェクト(ツリーやリンクリストなど)。

比較方法では、多くの場合、公開データだけでなく、個人データを直接比較します。

リンクリスト、グラフ、またはツリーを構成するノードのクラスの場合、兄弟のプライベートデータにアクセスできることがまさに必要です。知っているコード(クラスの一部)はデータ構造をいじくり回すことができますが、データ構造の外側のコードは内部に触れることはできません。

これらの2つのケースは、この言語機能が最初に開発されたときよりも日常のプログラミングではあまり一般的ではないことに注意してください。1990年代から2000年代初頭にかけて、C ++では、カスタムデータ構造と比較メソッドを構築することがはるかに一般的でした。たぶん、プライベートメンバーを再考する良い機会です。

于 2010-01-19T01:21:18.243 に答える
1

オブジェクトは単なるデータです。クラスには機能が含まれています。メンバー メソッドは、コンパイラが実行する優れたトリックです。実際には、暗黙の引数を持つ静的メソッドに似ています (拡張メソッドのようなものです)。それを念頭に置いて、オブジェクトを互いに保護することは意味がありません。クラスを互いに保護することしかできません。ですから、そのように機能するのは当然です。

于 2010-01-19T07:22:24.087 に答える
0

いいえ、これは必要です。メソッド コードはインスタンスに固有のものではなく、オブジェクトの型に固有のものです。(仮想メソッド) または宣言された変数の型 (非仮想メソッドの場合)。一方、非静的フィールドはインスタンス固有です...インスタンスレベルの分離がある場所です。

静的メソッドと非静的メソッドの唯一の違いは、静的メソッドは他のインスタンス ベースの (非静的) メソッドまたはフィールドにアクセスできないことです。変更なしで静的にすることができるメソッドは、インスタンスベースの構文を使用して呼び出された場所でコンパイラにエラーをスローさせることを除いて、静的にしても影響を受けません。

于 2010-01-19T00:45:05.140 に答える
0

特定の生徒の情報を調べる場合は、メソッドを静的に変更します。

  public static void ExamineStudentsMembers(Student student)
  {
     Console.WriteLine(student._studentsPrivateMember);
  }

次に、 を使用しますStudent.ExamineStudentsMembers(s1)。使用s1.ExamineStudentsMembers(s2)すると無効になります。

これが意図した目的でない場合は、メソッドを次のように書き直します。

  public void ExamineStudentsMembers()
  {
     Console.WriteLine(_studentsPrivateMember);
  }

上記は、次のように書くことによって使用されますs1.ExamineStudentsMembers()

于 2010-01-19T00:48:41.517 に答える
-1

オブジェクト スコープはセキュリティを意味するものではありません。ランタイム セキュリティを提供するのは OS の役割です。ランタイム オブジェクト インスタンス データ アクセスを制限するために言語固有のオブジェクト スコープに依存するシステムを設計するのはバグです。そうでない場合、すべての非オブジェクト指向言語は、定義上、安全ではありません。

于 2010-01-19T12:54:19.923 に答える