2016-03-07 12 views
5

複数のブール値(および整数)プロパティを持つオブジェクトがあります。私は、テストに使用される良いデータセットを持つために、多くの異なるプロパティを持つオブジェクトのコレクションを作成したいと考えています。私はvalue = 0/1/2/3/4/5、foo = TRUEと、elementw 6 * 2 * 2 = 24のリストを持っているように、この例については、例複数のプロパティを持つオブジェクトセットを作成する

public class A 
{ 
    public int value {get; set;} //want to try beetween 0 and 5 
    public bool foo {get; set;} 
    public bool bar {get; set;} 
    public bool boo {get; set;} 
} 

について

/false、bar = true/falseですが、booは常にfalseです。

私は、24行のコードを使用してこれを行うことができます。しかし、それはたくさんあり、もし私がブールをもう1つ持っていれば、それはラインの数を2倍にします。

私は、プロパティごとに一つのループを使用することができるが、私はそれがあまりにも多くのネストされたループを持っているための良い方法だとは思いません。私もこれを反射で行うかもしれませんが、これはあまりにも多くの仕事だと思いますか?

私はそれをより良くする別の方法があると思いますが、私はそれを見つけられません。

+2

は、「私はそれを持っているには良い方法だとは思いませんあまりにも多くのネストループ。なぜ、ここで行うには完全に合理的なものと思われる... – tolanj

+0

は、LINQのデカルト製品の例を見て、(HTTP [すべ​​ての可能な組み合わせの生成]の –

+0

可能な重複構築するのは非常に簡単で、素敵でなければなりません://のstackoverflowを。com/questions/3093622 /生成可能なすべての組み合わせ) –

答えて

3

この古いループベースのアプローチの問題点は何ですか?

var boolVals = new[] { true, false }; 
var intVals = new[] { 0, 1, 2, 3, 4, 5 }; 

var myList = new List<A>(); 

foreach(var foo in boolVals) { 
    foreach(var value in intVals) { 
     foreach(var bar in boolVals) { 
      foreach (var boo in boolVals) { 
       myList.Add(new A { value = value, foo = foo, bar = bar, boo = boo }); 
      } 
     } 
    } 
} 

追加するプロパティごとに新しいネストを追加する必要があります。このプロパティには、適切な値のセットを追加してループする必要があります。

このappraochは読みやすいコードの数行の中に自分の価値観のあらゆる可能な順列をFILS。

もちろん、少し醜いです。しかし、追加されたすべてのプロパティに1つずつネストするだけで増加します。

1

あなたは明示的に全置換ソリューションを求めていないので、私はランダムに行くことをお勧めします。あなたはコンストラクタを採用することができます...

public class A 
{ 
    public int value {get; set;} //want to try beetween 0 and 5 
    public bool foo {get; set;} 
    public bool bar {get; set;} 
    public bool boo {get; set;} 

    public A() 
    { 
    // initialize value, foo, bar, boo with desired default/random here 

    } 
} 

var myList = new List<A>(); 
for (int i=0; i<=24; i++) myLyst.add(new A()); 

これは私にはかなり読みやすく保守的なようです。新しいA()に引数を渡して、必要に応じてn番目の置換を計算することもできますが、これは問題の範囲を超えていると思います。

0

あなたは各プロパティの

を使用してこの反射と(同等のインデックスを経由して)値を追跡し、データ構造を行うことができますこれは、自動的にクラス内のすべてのプロパティを占め、あなたは他のプロパティタイプのためにそれを拡張することができます単にValuesFor辞書

using System; 
using System.Collections.Generic; 
using System.Reflection; 

public class Program 
{ 
    private static Dictionary<string, object[]> ValuesFor = new Dictionary<string, object[]>() 
    { 
     { typeof(int).ToString(), new object[] { 0, 1, 2, 3, 4, 5 } }, 
     { typeof(bool).ToString(), new object[] { true, false } } 
    }; 



    public static void Main() 
    { 
     var properties = typeof(A).GetProperties(BindingFlags.Instance | BindingFlags.Public); 
     int[] valueIndices = new int[properties.Length]; 

     do 
     { 
      createObject(properties, valueIndices); 
     } while (setNext(properties, valueIndices)); 

     Console.ReadKey(); 
    } 

    /// <summary> 
    /// This updates the valueIndex array to the next value 
    /// </summary> 
    /// <returns>returns true if the valueIndex array has been updated</returns> 
    public static bool setNext(PropertyInfo[] properties, int[] valueIndices) 
    { 
     for (var i = 0; i < properties.Length; i++) 
     { 
      if (valueIndices[i] < ValuesFor[properties[i].PropertyType.ToString()].Length - 1) { 
       valueIndices[i]++; 
       for (var j = 0; j < i; j++) 
        valueIndices[j] = 0; 
       return true; 
      } 
     } 
     return false; 
    } 

    /// <summary> 
    /// Creates the object 
    /// </summary> 
    public static void createObject(PropertyInfo[] properties, int[] valueIndices) 
    { 
     var a = new A(); 
     for (var i = 0; i < properties.Length; i++) 
     { 
      properties[i].SetValue(a, ValuesFor[properties[i].PropertyType.ToString()][valueIndices[i]]); 
     } 

     print(a, properties); 
    } 



    public static void print(object a, PropertyInfo[] properties) 
    { 
     Console.Write("Created : "); 
     for (var i = 0; i < properties.Length; i++) 
      Console.Write(properties[i].Name + "=" + properties[i].GetValue(a) + " "); 
     Console.Write("\n"); 
    } 



    public class A 
    { 
     public int value { get; set; } 
     public bool foo { get; set; } 
     public bool bar { get; set; } 
     public bool boo { get; set; } 
    } 
} 

現在createObjectに追加することにより、単にオブジェクトを作成し、オブジェクトを印刷するprintを呼び出します。代わりに、それをコレクションに追加することができますし、(テストを置く代わりに、print直接または)それを使用してテストを実行


フィドル - https://dotnetfiddle.net/oeLqc5

関連する問題