2016-08-03 13 views
0
namespace TestOOP 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 

    internal sealed class Student 
    { 
     private string name; 
    } 

    internal sealed class Course 
    { 
     private ICollection<Student> students; 

     public ICollection<Student> Students 
     { 
      get { return this.students; } 
      set { this.students = Students; } 
     } 
    } 

    class Program 
    { 
     static void Main() 
     { 
      var course = new Course(); 
      course.Students.Add(new Student()); 
      Console.WriteLine(course.Students.Count()); 
     } 
    } 
} 

これは私のコードです。それを実行すると、私はコースに学生を追加しようとする行のオブジェクトのインスタンスに設定されていないオブジェクトを取得します。インターフェースをフィールドとして使う方法を説明する助けが必要です。コレクションの施設interfaceをフィールドとして使用する方法は?

+0

この場合、値は「Students」プロパティ(またはバックフィールド「students」)に設定されないため、「null」であり、「Students.Count()」がスローされます。 – Sinatr

答えて

4

、それは建設中にそれらを初期化し、readonlyゲッターを介してそれらを公開することをお勧めします:

internal sealed class Course 
{ 
    readonly List<Student> students = new List<Student>(); 
    public ICollection<Student> Students 
    { 
     get { return this.students; } 
    } 
} 

これはStudentsプロパティがnullになることはありませんことを確認し、そして何のコードは置き換えることはできません別のインスタンスを持つバッキングフィールド。しかし、これはクラスを不変にしません。引き続きStudentsコレクションにアイテムを追加したり削除したりすることができます。あなたもautoimplemented読み取り専用プロパティを使用することができますC#6構文で

:あなたの問題はインタフェースではありません

internal sealed class Course 
{ 
    public ICollection<Student> Students { get; } = new List<Student>(); 
} 
+0

リストのすべての機能を使用したくない場合は、追加/削除/カウントのみですか? ICollection内にカスタムクラスを作成する必要がありますか? – sirSemite

+0

その場合、継承の代わりにcompositionを使うことをお勧めします。つまり、 'students'をプライベートフィールドにし、パブリックプロパティを完全に削除し、必要なパブリックメソッドだけを公開します(プライベートリストで動作します)。あなたが 'ICollection'から継承している場合は、あなた自身がそのインターフェースにすべてのメソッドを実装しなければなりませんが、それは間違ったアプローチです(*コレクションが変更されたときにイベントを発生させるカスタム' StudentsCollection'を必要としない限り* 「コース」は単なる「学生の集まり」ではない)。 – Groo

1

、それはあなたがあなたの変数には何も割り当てないという事実です。

private ICollection<Student> students; 

これは、それを修正します:あなたは、クラスのコースのためのコンストラクタを使用して、たとえば、不動産の学生の実際のインスタンスを作成する必要が

private ICollection<Student> students = new List<Student>(); 
0

internal sealed class Course 
{ 
    private ICollection<Student> students; 

    public ICollection<Student> Students 
    { 
     get { return this.students; } 
     set { this.students = Students; } 
    } 

    public Course() 
    { 
     this.Students = new List<Student>(); 
    } 
} 

インターフェース実際のクラスで実装する必要があります。

関連する問題