Ошибка аргументов типа в методе расширения LINQ - PullRequest
0 голосов
/ 26 января 2011

Я написал расширение LINQ, чтобы объединить 2 таблицы

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())
                    });
        }

Компилятор хорошо понимает расширение, но когда я пытаюсь написать

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

Я получил следующую ошибку:

Аргументы типа для метода .ToDetail (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, System.Func, System.Func, System.Func, System.Func, string) ' не может быть выведено из использования. Пытаться указание аргументов типа явно

Затем я попытался удалить параметры keyProperty и valueProperty из расширения, оно работает без ошибок. Я не знаю почему, может быть, компилятор запутался и не может определить параметр с таким же типом?

Буду признателен за любую помощь!

1 Ответ

1 голос
/ 26 января 2011

В объявлении функции вы используете один и тот же тип функции для аргументов rightProperty, keyProperty и valueProperty, поэтому обе эти функции должны иметь тип Func<TRight, TKey>.

Это означает, что при вызове функции тип r.ID, r.Key и r.Value должен быть одинаковым (чтобы компилятор C # мог вывести параметр типа TKey из этих двух). Я предполагаю, что в вашем примере, по крайней мере, один из этих трех отличается (вероятно, ID).

(Кроме того, поскольку вы конвертируете результат valueSelector и keySelector в строку, используя метод ToString, вероятно, нет причин для использования универсальных типов - функция, возвращающая object, должна сделать трюк).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...