2016-05-19 13 views
-1

このシナリオでは、TypeAとTypeBの両方から派生する基本型を作成できないため、メソッドにWhere:TypeBaseを追加できません。私はこれを解決する別の方法があるかどうかを見たいと思います。汎用またはオブジェクトパラメータを参照型に変換する方法

class TypeA 
{ 
    int number; 
    string someString; 
} 

class TypeB 
{ 
    int number; 
    decimal someDecimal; 
} 

private List<int> Test(object inputs) 
{ 
    List<int> rv = new List<int>(); 

    if (inputs is List<TypeA>) 
     inputs = (List<TypeA>)inputs; 
    else if(inputs is List<TypeB>) 
     inputs = (List<TypeB>)inputs; 

    foreach(item in inputs) 
    { 
     rv.Add(item.number); 
    } 
    return rv; 
} 
+2

'item'のタイプはどのようなものでしょうか?あなたはそれぞれの商品で何をしようとしていますか? –

+0

@JonSkeetアイテムはTypeAまたはTypeBのいずれかになりますが、それらの間で共有される共通の値を取得するだけで済みます。私は、ベースクラスまたはインターフェイスw /を使用してこれを行うことができることを知っています:BaseClassしかし、私は別の方法があるかどうかを知りたいです。 – user3953989

+0

各タイプの 'foreach'ループの中でどうやってやっていますか? –

答えて

1
private void GenericTest<T>(IEnumerable<T> inputs) 
{ 
    MethodInfo property = typeof(T).GetProperty(/*YOUR PROPERTY*/).GetMethod; 
    foreach (var input in inputs) 
    { 
     object value = property.Invoke(input, null); 
     // Logic 
    } 
} 

// To protect it from error 
public void Test(IEnumerable<TypeA> inputs) 
{ 
    GenericTest(inputs); 
} 

// To protect it from error 
public void Test(IEnumerable<TypeB> inputs) 
{ 
    GenericTest(inputs); 
} 

それでは、プロパティ名をTestメソッドに渡すのはなぜですか?

0

あなたはIEnumerableにキャストし、その後foreach -loop行うことができます。ロジックは、クラスごとに異なることが必要である場合

private void Test(object inputs) 
{ 
    // you can also change the parameter to IEnumerable to take advantage of compile-time type-checking. 
    var items = inputs as IEnumerable; 
    if (items == null) 
     throw new ArgumentException("inputs"); 

    foreach (var item in items) 
    { 

    } 
} 

を、これを使用する:

private void Test(object inputs) 
{ 
    var typeAs = inputs as IEnumerable<TypeA>; 
    if (typeAs != null) 
    { 
     foreach (var item in typeAs) 
     { 

     } 
     return; 
    } 
    var typeBs = inputs as IEnumerable<TypeB>; 
    if (typeBs != null) 
    { 
     foreach (var item in typeBs) 
     { 

     } 
     return; 
    } 

    throw new ArgumentException("inputs"); 
} 
0

独立して繰り返し処理する場合は、追加の作業を行いません。

class Program 
{ 
    private void Test(object inputs) 
    { 
     if (inputs is List<TypeA>) 
      loop((List<TypeA>) inputs); 
     if (inputs is List<TypeB>) 
      loop((List<TypeB>)inputs); 
    } 

    private void loop(IEnumerable<TypeA> inputs) 
    { 
     foreach (var input in inputs) 
     { 
      logic(input.i); 
     } 
    } 

    private void loop(IEnumerable<TypeB> inputs) 
    { 
     foreach (var input in inputs) 
     { 
      logic(input.i); 
     } 
    } 

    private void logic(int i) 
    { 
     // magic happens here 
    } 
} 

class TypeA 
{ 
    public int i; 
} 

class TypeB 
{ 
    public int i; 
} 

しかし、世界のすべてのものの愛のために、これをしないでください。

あなたが実際にいくつかの理由で一度にリストを反復しなければならない、とあなたはテストのみTypeAsとTypeBsで呼び出されますを知って場合は、dynamic typeでこれを扱うことができます。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var w = new TypeA {i = 8}; 
     var x = new TypeA {i = 16}; 
     var y = new TypeB {i = 32}; 
     var z = new TypeC(); // don't pass this to Test! 
     var l = new List<dynamic> {w, x, y}; 
     Test(l); 
    } 

    private static void Test(IEnumerable<dynamic> inputs) 
    { 
     foreach (var input in inputs) 
     { 
      logic(input.i); 
     } 
    } 

    private static void logic(int i) 
    { 
     // magic happens here 
    } 
} 

class TypeA 
{ 
    public int i; 
} 

class TypeB 
{ 
    public int i; 
} 

class TypeC {} // no members 
+0

笑それは私が避けようとしているものです:) – user3953989

+0

なぜあなたはリストを別々に反復することを避けようとしていますか?つまり、最初に合併して得たいものは何ですか?私はあなたがしてはならないと言っているわけではありませんが、あなたのユースケースを理解したいと思います。 –

関連する問題