2010-12-06 22 views
4

デザイン時にこれらの値の型と数はわかりませんが、任意の数の型を保持できるクラスを設計する必要があります。たとえば、2つのint値と1つのint値または2つのint値でクラスを初期化できます。私はまた、可能な限りボクシングを避けたい( 'オブジェクト'タイプを使用して)。名前を持っているそれぞれのタイプも、値を保持しているので、内部辞書は型パラメータが不明なクラスの設計

Dictionary<string,object> nameValues;//Boxing! 

ようになりますと、コンストラクタは

MyClass(params object[] values) { ... } 

のようになります。私はこの

MyClass mc = new MyClass("intVal",3,"doubleVal",3.5,"dateTimeVal",DateTime.Now); 
のようにインスタンスを構築することができ

可能な限りボクシングを避けるより効率的なデザインに関する提案。

編集: '文字列'の値もパラメータとして指定できます。私は当初、バリュータイプだけを言及しましたが、それはもはや事例ではありません!

+0

を使用しています下のようなものかもしれボクシングを使用して。一方、あなたが何をしたいかを教えてくれれば、誰かがより良い解決策を思いつくかもしれません。 – decyclone

+0

値の型のパラメータには何か制限があります。2,3,4,5 – TalentTuner

+0

@decyclone実際には、実際に私が述べたことを達成したいと思います。つまり、各値の型に関連する名前がある任意の数の値型。 – alwayslearning

答えて

2

個人的に私は少しボクシングの怖さを感じることはありません。あなたがプロファイリングして問題であることが証明されていない限り、これはおそらくあなたの問題の中で最も少ないでしょう。しかし、どのようにアノン型について:

var mc = new { intVal = 3, doubleVal = 3.5, dateTimeVal = DateTime.Now }; 

唯一の問題は、この方法の外が戻って、これらの値を取得する唯一の方法は、リフレクション経由であるということです。どちらもではなく、に問題があります。しかし、多くの点で、Dictionary<string,object>は(はるかに太りすぎながら)はるかに簡単です。

2

は、事前に可能なタイプを知っている場合、あなたが戻って値を読み取るとき、あなたはボクシングを必要としないタイプごとに別々の辞書を使用することができ、この

Dictionary<string, ValueType> x = new Dictionary<string, ValueType>(); 
x.Add("1",1); 
x.Add("2", 23.33m); 
x.Add("3", new MyStruct()); 
x.Add("4", new object()); // compile-time error 
+0

を参照してください。私は指摘したように、 '文字列'の値も許容されているので、辞書の 'ValueType'は使用できません。 – alwayslearning

+0

文字列は値型ではないので、 –

+3

型の「ValueType」は(恐らく混乱して)囲まれていません。 –

2

を試してみてください。たとえば、既存のコードの構造を使用して

class MyClass 
{ 
    private Dictionary<string, int> intValues = new Dictionary<string, int>(); 
    private Dictionary<string, double> doubleValues = new Dictionary<string, double>(); 
    private Dictionary<string, DateTime> dateTimeValues = new Dictionary<string, DateTime>(); 

    public MyClass(params object[] values) 
    { 
     if (values.Length % 2 != 0) 
      throw new ArgumentException("invalid values!", "values"); 
     for (int i = 0; i < values.Length; i += 2) 
     { 
      string key = values[i].ToString(); 
      object value = values[i + 1]; 
      if (value is int) 
       intValues.Add(key, (int)value); 
      else if (value is double) 
       doubleValues.Add(key, (double)value); 
      else if (value is DateTime) 
       dateTimeValues.Add(key, (DateTime)value); 
     } 
    } 
} 
0

は、私はあなたがすることなく、これを達成することができますどのように表示されていない

public class ValueHolder 
{ 
    public ValueType[] Values { get; set; } 
    public string[] NonValueType { get; set; } 
} 

public class SomeValueType<T> where T:ValueHolder 
{ 
    Dictionary<string, T> tempDict = new Dictionary<string, T>(); 


    public SomeValueType(T val,string keyName) 
    { 
     if(!tempDict.Keys.Contains(keyName)) 
      tempDict.Add(keyName, val); 
    } 

} 

 ValueType[] arr = new ValueType[] { 1, 1.1, DateTime.Now }; 
     ValueHolder vh = new ValueHolder(); 
     vh.Values = arr; 
     vh.NonValueType = new string[] { "temp", "s" }; 
     SomeValueType<ValueHolder> temp = new SomeValueType<ValueHolder>(vh, "key"); 
+1

'ValueType'へのキャストは実際にはボクシング操作です –

+0

@Marc:これを指摘してくれたありがとうMarc:これを説明するリンクを投稿してください。実際には間違った前提にあったのですか? – TalentTuner

+0

私は良いリファレンスがありませんコンパイル時に構造体として扱うことができる、具体的な、正確な型*を知っているときだけです。おそらく、単に 'ValueType'自体が' class'であるという事実は、あなたにとって十分な証拠です。それ以外の場合は、ILでボックス操作を調べてください。 –

関連する問題