2015-10-28 3 views
1

У меня есть универсальный метод, как:Как иметь анонимный тип возврата в общий метод (например, выберите метод в LINQ)

IEnumerable<TResult> Select2<TSource, TResult>(Func<TSource, TResult> selector) 

и вызов метода:

var r = Select2(p => new { FullName = p.FirstName + " " + p.LastName }); 

Как я могу установить TResult в моем вызове метода? В LINQ, когда и использовать от выбора метода вы можете увидеть тип TResult как « enter image description here Update

Например, у меня есть свой собственный ORM и выбора метода сгенерировать T-Sql выберите query.with мой метод, который я хочу задать конкретный столбец и получить результат от моего specification.If я называю метод, как

var r=Select2<Person,?>(p=> new{Name=p.FirstName ,Family=p.LastName}) 

Я хочу, чтобы сгенерировать отборный с FirstName и LastName колонки и типа возвращаемого значения только имеет имя и семейная собственность

+0

Пожалуйста, исправьте код, что означает '( selector), который должен означать синтаксис? –

+0

Кроме того, просто попробуйте опустить параметры общего типа для вызова, посмотрите, будет ли компилятор выводить типы для вас. –

+0

Короткий ответ: невозможно. Если вам нужно перейти в 'selector', почему бы не вызвать' selector' напрямую? – qxg

ответ

3

Я предполагаю, что сигнатура метода

TResult Select2<TSource, TResult>(Func<TSource, TResult> selector) 

Просто писать var r = Select2(p => new { ... }) не работает, поскольку компилятор может только определить тип TResult, а не тип TSource.

Создание общих типов явных тоже не работает, потому что, как вы видели, вы не можете сделать это для анонимного типа.

Что вы можете сделать, это помочь компилятору написания лямбда-другому:

var r = Select2((Person p) => new { ... }); 

Таким образом, компилятор знает тип TSource и может определить тип TResult.

+0

@Drik его сработало. Может быть, вы больше объясните свой код? как ваш код поможет компилятору вывести TResult? почему в моем компиляторе кода con не вывести TResult? –

+0

@ M.Azad Проблема заключается не в том, что компилятор не может вывести тип «TResult», он на самом деле может. Но для 'Select2 (p => new ...)' он не может вывести тип 'TSource'. – Dirk

+0

@Drik Я хочу знать, есть ли причина, по которой он не может вывести тип TSource? –

0

Я не могу сказать, что я предпочел бы сделать это, но вы должны использовать динамику в этом случае:

IEnumrable<dynamic> Select2<TSource>(Func<TSource, dynamic> selector); 
//method call 
var r=Select2<Person>(p=> new{FullName=p.FirstName +" "+p.LastName}); 

Если посмотреть на микро ORMs как Dapper, вы увидите, что они также поддерживают вызовы методов возвращающих динамические типы.

+0

Downvoter, пожалуйста, просветите меня. Я здесь, чтобы узнать :) –

+0

Хороший ответ, upvoted – Fabjan

+0

@GertArnold - 'dynamic' имеет свои цели, когда типы не могут быть выведены, но в этом случае есть простое строго типизированное решение - Dirk опубликовал его. Поэтому использование 'dynamic' является слабым решением, которого следует избегать. – Enigmativity

Смежные вопросы