2016-05-13 24 views
1

私は触れられないクラスオブジェクトのセットを持っています。それらのすべてには、他の関数で一般的な方法でアクセスしたいIDプロパティがあります。多対1のクラス関係の作成

ここでは簡単のため、私の問題の例を示します。

class Example1 { 
    int ID { get; set;} 
} 
class Example2 { 
    int ID { get; set; } 
} 

私はこの2つのクラスや、彼らがしているライブラリのいずれかを編集することはできませんよ。私もExample1またはExample2のいずれかから来ることができるIDを期待する機能を持っている

。これを処理するために、私はいくつかの解決策を考え出しましたが、これを解決する適切な方法は何か不思議です。

私は可能性:様々なクラスIDをアクセスするための

  1. 使用動的なクラス。
  2. 反射を使用して、任意のタイプからIDパラメータを引き出します。
  3. から関連する部分を抽出することができます別のフィルタ機能を書くのデータを収集し処理するためにExample1ViewModelでコピーコンストラクタをExample1ViewModel : Example1, IIdentifiableObjectしてからは、私の機能でIIdentifiableObjectを期待するように、新しいクラスを作成することによって、奇数継承を使用して実装しますどちらかのクラスと結果を提供します。

これらのソリューションは特に優れていないようです。コードでこのような多対1の関係をどのように処理する必要がありますか、これを処理するためにC#が提供するツールはありますか?

+1

Example1、Example2クラスに拡張メソッドを追加できますか? –

答えて

0

ここでは、私たちが使い終わった理由とその理由を説明します。

私たちは、それは、次の2つの基底クラスかかる継承構造を使用している:

FooExample 
BarExample 

をし、次の

IExample 
FooExampleModel : IExample 
BarExampleModel : IExample 

FooExampleModelBarExampleModelクラス彼らを受け入れるコンストラクタを持っている両方でそれらをラップしますラッピングしています。

この重要性は、事前にデータを操作することなくIExampleインスタンスを受け入れるメソッドを作成できることです。さらに、動的型またはリフレクションを使用するのとは異なり、このソリューションはコンパイル時のエラーチェックを提供します。

残念ながら、拡張メソッドを使用しても機能しません。私たちが望むように、同じメソッドを2つの異なるオブジェクト型で呼び出すことはできますが、それらのオブジェクトを汎用型として個別の関数に渡すことはできません。

このすべての結果は、これが今できることである。これは、これを実現するための最良の方法のように見えるそのわずか総LINQクエリのほか

var foos = new List<FooExample>(); //Pretend there is data here 
var bars = new List<BarExample>(); 
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo)) 
        .Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar))) 
        .ToList(); // Force evaluation before function call 
DoSomethingOnIExamples(examples); 

DoSomethingOnIExamples(...)IEnumerable<IExample>引数を受け取る関数です) 。明らかに、このミックスにはより多くのタイプが追加されるので、このソリューションはあまりうまくいかないでしょう。

2

あなたはリフレクションを使用して静的メソッドを追加できるクラス

public static class MyExtensions 
    { 
     public static int GetId(this Example1 ex) 
     { 
      return ex.Id; 
     } 

     public static int GetId(this Example2 ex) 
     { 
      return ex.Id; 
     } 
    } 
+0

これは動作しますが、まだラッピングが必要です。私は関数の外からこれらを呼び出し、結果を渡す必要があります。それは良い解決策ですが、例えばExample1やExample2のように関数を制限する方法を知っていますか?または、ラッパーが必要ですか?関数の前に 'examples.Select(ex)=> ex.GetId())'のようなものを考える方法はありませんでした。 –

+0

私はあなたがquesionを立っているとは思わない。拡張メソッドは、今あなたがオブジェクトを作成するときよりも、それは機能を持っています。すなわち:Example1 ex = new Example()。あなたはex.GetId()を持っています。 –

+0

ここでの目標は、同じ種類のものを取得したり、他の一般的な実装を可能にすることです。私は拡張メソッドを追加することで何が得られるか分からない。 GetId()を呼び出してオブジェクトIDプロパティを呼び出すだけでは何が得られますか? –

0

のための拡張メソッドを使用して可能な解決策:

public static int GetId(object obj) 
    { 
     Type type = obj.GetType(); 
     return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null)); 
    } 

その後、idプロパティの値を取得する任意のオブジェクトでそれを呼び出すことができます。

+0

リフレクションまたはダイナミッククラスのソリューションに関する私の懸念は、どちらもランタイムベースのエラーチェックが必要だということです。可能であれば、コンパイル時にエラーが発生するのが理想的です。 –