2011-03-11 4 views
0

以下のコンソールアプリケーションでは、プログラムがバスケットボールチームを作成しようとしていることがわかります。その後、プレーヤーとコーチをチーム。ジェネリッククラスのジェネリックリストをジェネリッククラスで操作する方法

具体的なクラス(Lakers()、Player()、およびCoach())が継承する汎用クラス(TeamおよびPerson)を実装しています。

プログラムは、team.MembersリストにPersonオブジェクトを追加しようとした時点でビルド例外をスローします。

例外が読み:

を 'System.Collections.Generic.List> .Add(人)' の最良のオーバーロードされたメソッドの試合は、いくつかの無効な 引数があります。

メンバがジェネリックPlayerの総称リストとして定義されている場合、コンパイラでジェネリックPlayer(KobeとPhil)をメンバーリストに追加できない理由を理解できません。

エラーの原因とその回避方法を説明できますか?

また、以下のサンプルプログラムが一般的にジェネリックスを実装する方法ではないかどうかを私に記入することができますか?言い換えれば、以下のプログラムのエラーを考えれば、ジェネリックスを実装し、通常の抽象クラスに固執するべきではない理由が不思議に思えます。

ところで、してくださいあなたはレイカーズが好きではないという理由だけではないダウン投票を行う;)

class Program 
    { 
     static void Main(string[] args) 
     { 
      //Create a team 
      Team<Lakers> team = new Lakers(); 

      //Create a player then add the player to the list of team members 
      Person<Player> p = new Player(); 
      p.Name = "Kobe"; 
      team.Members.Add(p); //Invalid argument exception here 

      //Create a coach then add the coach to the list of team members 
      Person<Coach> c = new Coach(); 
      c.Name = "Phil"; 
      team.Members.Add(c); //Invalid argument exception here 

      //Display the members of the team 
      team.Members.ForEach(n => Console.WriteLine(n.Name)); 
      Console.ReadLine(); 
     } 
    } 

    //A generic class containing a generic list of a generic type 
    abstract class Team<T> 
    { 
     public List<Person<T>> Members = new List<Person<T>>(); 
    } 

    //A concrete basketball team 
    class Lakers : Team<Lakers> 
    { 
    } 

    //A generic class that represents a person 
    abstract class Person<T> 
    { 
     public string Name { get; set; } 
    } 

    //A concrete person that represents a basketball player 
    class Player : Person<Player> 
    { 
    } 

    //A concrete person that represents a basketball coach 
    class Coach : Person<Coach> 
    { 
    } 

答えて

1

チームをタイプLakersおよびPersonとしてタイププレーヤとして宣言しているためです。それらは等しくはありません。

リストを制約する必要がありますか?あなたはそれをPersonとして宣言できませんか?私は自分のカスタムジェネリッククラスでの作業に新たなんだということで

abstract class Team<T> 
    { 
     public List<Person> Members = new List<Person>(); 
    } 
+0

、私は決して実現/クラスシグネチャ(抽象クラ​​スのチーム)で全体クラス定義内タイプを指定することを考えました。私は今、 "公開リスト>メンバー=新しいリスト>();"サンプルプログラムの設計を考えると、実際には理にかなっていません。 – Jed

1

理由だけではなく:ジェネリック医薬品の

//An abstract class that represents a person 
    abstract class Person 
    { 
     public string Name { get; set; } 
    } 

    //A concrete person that represents a basketball player 
    class Player : Person 
    { 
    } 

    //A concrete person that represents a basketball coach 
    class Coach : Person 
    { 
    } 

の使用は完全に思えます不要。単純な階層で十分です。

1

あなたは継承とジェネリックを混同しているようです。技術的には違いはありますが、汎用クラスはテンプレートであり、is-a関係ではありません。通常の継承はあなたがここですべて必要です。