2016-10-21 9 views
6

は、私は以下の型を持っていると言う:ジェネリック型を含む配列を宣言するにはどうすればよいですか?

public class Field<T> 
{ 
    public string Name { get; set; } 
    public T Value { get; set; } 
} 

どのように私は、このようなフィールドの配列が含まれています変数を宣言することができますか?

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

が、私は、次のコンパイル時例外を取得:私は、次の試したジェネリック型「フィールド」を使用して

を必要とする1型引数

私もvar customFields = new Field<object>[]を試みたが、

暗黙のうちに、 'Field'タイプを 'F'に変換できません。マティアスは、それがためにそのように行うことはできません言ったようにield」

暗黙的にタイプ変換できません 『フィールド』 『にフィールドをフィールド『

+4

各ジェネリックタイプは、*異なるタイプ*です。したがって、異なるタイプのインスタンスの配列を作成しようとしています。これは不可能です。これは 'string'と' int'値を格納する配列を作成しようとするようなものです。ただし、[共分散](https://msdn.microsoft.com/en-us/library/dd799517(v = vs.110).aspx)を参照してください。 –

答えて

12

『に』フィールド』

は、暗黙的にタイプを変換できません』 Field<int>Field<string>は完全に異なるタイプです。あなたにできることは次のとおりです。

は、ベースFieldを作成し、一般的なされていない。そして、

public class Field 
{ 
    public string Name { get; set; } 
} 

public class Field<T> : Field 
{ 
    public T Value { get; set; } 
} 

そして:マティアスは、ダウンキャストがのValueを取得するために必要とされるであろうコメントしたよう

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

他の種類。 Valueの種類が異なる場合、実行する特定のロジックがある場合は、それを処理するための良い方法は、Factoryデザインパターンを使用することです。工場では、それぞれFieldの正しい「FieldHandler<T>」が返送され、それがダウンキャストされ、操作が実行され、必要なものが返されます。

+5

FYI:要素の 'Value'プロパティを得るためにジェネリック型にダウンキャストする必要があります。 –

+0

@MatiasCicero - Ya ...それは本当です.. –

+0

非常に良いアイデア! Matiasが述べたように、値を取得するためにはキャストする必要がありますが、特定のケースでは、文字列、int、およびDateTimeのみをサポートしているので大したことではありません。ちなみに、私はTをこれらの3つのタイプだけに制限できるかどうかは誰にでも分かりますか? 'T:string、int、DateTime'の行に沿ったもの – desautelsj

2

もう1つのことは、すべてのタイプ(Object)に共通の基本クラスを使用することです。

class Field 
{ 
    public string Name { get; set; } 
    public Object Value { get; set; } 
} 
var customFields = new Field[] 
{ 
    new Field { Name = "nickname ", Value = "Bob" }, 
    new Field { Name = "age", Value = 42 }, 
    new Field { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

しかし、これはcustomFieldsの消費者にはいくつかの種類の処理をオフロードされますが、特定のフィールド名に関連付けられた値の型が知られている場合は問題ないはずです。

+0

私はあなたの最初のアプローチに同意し、それはなぜ私のupvoteしかし版の下にある - その場合は..なぜジェネリックを使用しない?.. :) –

+0

あなたはそうです!私はホワイトリスト形式の場合だけ追加するつもりですが、ジェネリックスでも ':T [:types allowed]'の使い方で制限できます。あなたのupvoteありがとう:) –

関連する問題