2017-11-02 2 views
-1

私はこの一般的なコンセプトを繰り返し苦労しています。私は、SQLの文字列のリストを選択し、LINQクエリを持って[選択]を呼び出して、文字列を摂取してオブジェクトを返す静的メソッドを提供:ランタイムで作成されたデリゲートとオブジェクトを使用する

MyDataContext context = new MyDataContext(); 
var list = (
    from t in context.GetTable<FooTable>() 
    where t.FooType = userProvidedString 
    select t.SomeColumn).ToList() 
     .Select(colValue => MyClass.FromString(colVal)) 
     .ToList(); 
int unique = list.Distinct(new MyClassComparer()).Count(); 

私が使用するさまざまな「プロファイル」の一握りを持っています同じクエリですが、タイプは異なります。たとえば、MyClassに加えて、MyOtherClassには、文字列パラメータを受け取り、それ自身のインスタンスを返すFromStringメソッドもあります。クエリからリストを取得した後、それをDistinctで呼び出して、実行時に再び決定されるコンストラクタデリゲートを提供したいとします。

私がこの種のことを常に実行している問題は、ビルド時のタイプです。

Type comparerType = Type.GetType(String.Format("MyNamespace.{0}Comparer", userProvidedString)); 
ConstructorInfo ctor = comparerType.GetConstructor(new Type[] { }); 

しかし、私はctorの上で呼び出しを呼び出すとき、私はまだキャストする必要があるオブジェクトで終わる:私は、私はこのような比較演算子を作成することができます知っています。私はこれができると確信しています、そして、私は単にいくつかの重要な概念を欠いています。私に恵みを届けてください! 事前に感謝します...

+2

_「これができると確信しています」_何ができるのかは確実ですか?あなたの質問は非常に不明です。最初にリフレクションを使用してコンバーターを作成する理由は何ですか?リフレクションを使用しているとすれば、リフレクションAPIが新しく作成したオブジェクトに強く型付けされた参照を返す方法があると思われるのはなぜですか?リフレクションAPIは、どのようなタイプのオブジェクトを先験的に作成するのですか?あなたが何を求めているかを明確に示す良い[mcve]を提供してください。 _precisely_コードが現在何をしているのか、そして何を代わりにしたいのかを説明してください。 –

+1

これは関数内でこれを折り返し変換器/比較関数を渡すことはできませんか? 'Func '& 'IConparer ' params – James

+0

上記の2つのコメントに同意してください。あなたは 'IComparer 'を受け入れ、返すようなFactoryメソッドを持つように 'Distinct()'メソッドを書いているようです。適切な状況のインスタンス?例えば反射は必要ない。 – zaitsman

答えて

0

"建設的なコメント"は私を正しい方向に向かわせてくれました。

public void Foo() 
{ 
    string dataType = "MyClass"; // Pretend this string was specified by the user 
    Type t = Type.GetType(dataType); 
    Type u = Type.GetType(dataType + "Comparer"); // Implements IEqualityComparer<MyClass> 
    MethodInfo method = this.GetType().GetMethod("GetUniqueItemCount", BindingFlags.Instance | BindingFlags.NonPublic); 
    MethodInfo generic = method.MakeGenericMethod(t, u); 

    int count = (int)generic.Invoke(this, new object[] { "some data blah blah" }); 
} 

private void GetUniqueItemCount<T, U>(string data) where T : class 
                where U : IEqualityComparer<T>, new() 
{ 
    MyDataContext context = new MyDataContext(); 
    var list = (
     from v in context.GetTable<SomeTable>() 
     select v.SomeColumn).ToList() 
      .Select(cellValue => Activator.CreateInstance(typeof(T), new object[] { cellValue }) as T) 
      .ToList(); 
    return list.Distinct(new U()).Count(); 
} 

残念ながら、私は「新しいTは()」のみパラメータなしのコンストラクタを使用することができますので、Activator.CreateInstanceを使用する必要がありました。これは、クエリ結果セットの各項目に対して呼び出されているため、あまり役に立ちません。

私がTとUを作成してメソッドを呼び出すために行ったすべての反射物は、私の質問の投稿で参照していたものです(避けることを望みます)。このソリューションはここに私の意図を完全に示すはずですので、よりクリーンなアプローチを知っていればチャイムしてください。

もう一度お世話になります!

関連する問題