2011-01-26 19 views
0

に、私は2つのテーブルタイプ引数エラーLINQの拡張メソッド

public static IEnumerable<ObjectDetail<TLeft, string>> ToDetail<TLeft, TRight, TKey>(this IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TKey> leftProperty, Func<TRight, TKey> rightProperty, Func<TRight, TKey> keyProperty, Func<TRight, TKey> valueProperty, string keySelector) 
     { 
      return (from l in left 
        join r in right on leftProperty(l) equals rightProperty(r) into one 
        select new 
        { 
         l, 
         one 
        }).AsEnumerable().Select(q => new ObjectDetail<TLeft, string> 
        { 
         Item = q.l, 
         Meta = q.one.Where(m => keySelector.Contains(keyProperty(m).ToString())).ToDictionary(m => keyProperty(m).ToString(), m => valueProperty(m).ToString()) 
        }); 
     } 

コンパイラに参加するためにLINQの拡張を書いたがうまく拡張を理解するが、私は

var result = left.ToDetail(right, l => l.ID, r => r.ID, r => r.Key, r => r.Value, "Key"); 

を書くしようとすると、私は、次のエラーを得ました:

The type arguments for method .ToDetail(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, System.Func, System.Func, System.Func, System.Func, string)' cannot be inferred from the usage. Try specifying the type arguments explicitly

次に、拡張子からkeyPropertyパラメータとvaluePropertyパラメータを削除しようとしましたが、何の誤りもなくうまくいく。私はなぜ、コンパイラが混乱し、同じ型のパラメータを決定できないのか分かりません。

ご協力いただけると助かります。あなたの関数の宣言で

+1

関連する型の宣言を投稿できますか?おそらく 'right'のソース型の' Key'と 'Value'プロパティは異なる型ですか?あるいは 'IDの種類は異なるかもしれませんか?これらのいずれかが、おそらく実際の論理エラーであるタイプ推論エラーを引き起こします。 – Ani

+0

KeyプロパティとValueプロパティは同じ型です。それらはすべて文字列です。左右のIDは同じです。 – ByulTaeng

答えて

1

は、あなたがrightPropertykeyPropertyvalueProperty引数の同じ関数型を使用するので、これらの機能の両方がタイプFunc<TRight, TKey>を持っている必要があります。

これは、関数を呼び出すとき(C#コンパイラは、これら2つからTKey型パラメータを推測することができるように)、r.IDr.Keyr.Valueのタイプは同じでなければならないことを意味しています。私の推測では、あなたの例では、これらの3つのうちの少なくとも1つが異なっています(おそらくID)。

(あなたがToStringメソッドを使用して文字列にvalueSelectorkeySelectorの結果を変換しているので、別に、あなたがジェネリック型を使用する必要がない理由は、おそらくありません - objectを返す関数は、トリックを行う必要があります)。

+0

説明をありがとう!それは私の多くを助けます。 – ByulTaeng