2016-03-25 11 views
1

私はC#でプロジェクトを進めています。 私はクラス名の国家のためのテンプレートを使用しています、ここにコードがある:ジェネリック型エラーを使用しているC#のテンプレート

class State<T> 
{ 
    private T state; //so T could be string or Cell 
} 

と私は、Cell

public class Cell 
{ 
    int currentRow,currentColumn; 
    Char value; 

    public Cell() 
    { 
    this.currentRow = 4; 
    this.currentColumn = 7; 
    this.value='0'; 
    } 
} 

という名前のクラスでそれを初期化する今、私は新しいState<Cell>が私の最初になりたいです状態、と言って:

public class Maze 
{ 
    public State<Cell> initialState;   
    public void CreateMaze(string name, int type) //creating maze 
    {  
    Board Maze = new Cell[size, size]; //board is matrix of cells 
    currentRow = random.Next(0, size); 
    currentCol = random.Next(0, size); 
    Maze[currentRow, currentCol].value = '*'; 
    initialState = State<Maze[currentRow, currentCol]>; 
    } 
} 

は私にエラーを与える ヘルプ「一つの引数を必要とジェネリック型を使用して」..?

+3

ジェネリックは、オブジェクト(つまりクラスのインスタンス)と値ではなく、型(つまりクラスまたは値型)によってパラメータ化されます。 – TerraPass

+2

@TerraPassのように、オブジェクトのインスタンスを型パラメータとして使用しようとしています。あなたはそれをすることはできません – Jonesopolis

+0

私はどのように割り当てを行うのですか?まだ状態です –

答えて

1
initialState = State<Maze[currentRow, currentCol]>; 

型パラメータ(State<T>T)はクラスまたは他のタイプではなく、オブジェクトまたは値にする必要があるので、これは、飛ばないであろう。

MazeクラスのinitialStateフィールドは、State<Cell>として正しく宣言されています。あなたはState<T>に何のコンストラクタを宣言していないので、 はしかし、あなたはこのフィールドを初期化するために行うことができる唯一のことは、その値としてnullを残しての外、次のとおりです。

initialState = new State<Cell>(); 

このラインはタイプState<Cell>の新しいオブジェクトを作成します。タイプState<Cell>は、実行時に "Reification"と呼ばれるプロセスを使用して定義した汎用State<T>に基づいて作成されます(詳細はthis answerを参照してください)。結果として得られるのは型(あなたの場合のクラス)です。基本的にはState<T>であり、体内にTの出現がすべてCellで置き換えられています。

State<T>にある唯一のものは1つのプライベートフィールドなので、このクラス(およびそのインスタンス)はかなり役に立たないです。

State<T>を使用するには、そのstateフィールドをpublicとマークできます。オプションで、プロパティにそれを変更し、多分、コンストラクタを宣言することができます。

class State<T> 
{ 
    public T state {get;set;} 

    public State(T state) 
    { 
     this.state = state; 
    } 
} 

今、あなたはそのようMazeであなたのinitialStateを初期化することができます

initialState = new State<Cell>(Maze[currentRow, currentCol]); 

を(サイドノートとして、命名避けるんあなたの変数は大文字で始まります。大文字の名前は通常、C#のクラスやメソッドに使用されるため、StackOverflowのシンタックスハイライターでさえ混同されています。)

あなたはinitialStateに保存されているCellインスタンスにアクセスすることができます。単にinitialState.stateと表示されます。

1

あなたはC++とC#を混同していると思います。

C++のテンプレートとは異なり、型のインスタンスを使用してジェネリック型にアクセスすることはできません。タイプのという名前を使用する必要があります。私はあなたがここで何をしたいのかを推測することができます

initialState = State<Maze[currentRow, currentCol]>; 

:これは、この行は、いくつかの補正が必要であることを意味します。私はプロパティがMaze[currentRow, currentCol]である新しいState<Cell>オブジェクトを作成したいと思います。

うまくいけば、私は正しいです。

C#では、新しいオブジェクトを作成する必要があるたびに、newキーワードを使用して、その型のコンストラクタを呼び出す必要があります。 「!stateフィールドがまだ設定されていない。しかし待って!」

initialState = new State<Cell>(); 

:だから、これを実行する必要がありますあなたは叫んだ。はい、現時点ではプライベートフィールドなので設定できません。

  • これをプロパティ(推奨)にすることもできます。
  • 公開に変更します。

あなたがプロパティにそれを有効にした場合、それは次のようになります。

public T MyState { 
    get; set; 
} 

また、あなたはそれをやりたいかどうか知らない、それは不変にすることができます。

public T MyState { 
    get; 
} 

その後、状態パラメータを取るコンストラクタを書いて、プロパティにそれを割り当てる:私はあなたを考える

initialState = new State<Cell>(Maze[currentRow, currentCol]); 

public State(T state) { 
    this.MyState = state; 
} 

は今、あなたはこのようなあなたのState<Cell>を初期化することができます今考えてみましょう。

ジェネリッククラスのプロパティ/フィールドを設定することはできません。クラスのインスタンスをジェネリック型のパラメータを置く場所に置くだけです。代わりに代入文でプロパティ/フィールドを手動で設定する必要があります。

関連する問題