I am writing a generic extension method for IEnumerable for mapping a list of objects to another list of mapped objects. This is how I would like the method to work:
IList<Article> articles = GetArticles();
return articles.Map<ArticleViewModel>(_mappingEngine);
This is the method:
public static IEnumerable<T2> Map<T1, T2>(this IEnumerable<T1> list, IMappingEngine engine)
{
return list.Select(engine.Map<T1, T2>);
}
However articles.Map<ArticleViewModel>(_mappingEngine);
gives a compile error.
The problem is that the type inference for T1 doesn't work. I have to explicitly call it like this instead:
articles.Map<Article, ArticleViewModel>(_mappingEngine);
If I create an extension method with only one parameter T1 like this:
public static IEnumerable<T1> DummyMap<T1>(this IEnumerable<T1> list, IMappingEngine engine)
{
return list;
}
Then I can call it like this, without having to specify T1:
articles.DummyMap(_mappingEngine);
Is there are reason why the compiler can't infer the type of T1 in the extension method for Map?
The problem is that the type inference for T1 doesn't work
Actually, the problem isn't T1 - it is T2; return types are not used in this inference. So you can't do that. One option might be a fluent API, for example:
return articles.Map(_mappingEngine).To<SomeT2>();
with something like:
public static MapProjection<T1> Map<T1>(this IEnumerable<T1> list, IMappingEngine engine)
{
return new MapProjection<T1>(list, engine);
}
public class MapProjection<T1>
{
private readonly IEnumerable<T1> list;
private readonly IMappingEngine engine;
internal MapProjection( IEnumerable<T1> list, IMappingEngine engine)
{this.list = list; this.engine = engine;}
public IEnumerable<T2> To<T2>()
{
return list.Select(engine.Map<T1, T2>());
}
}
assuming that the interface is something like:
public interface IMappingEngine {
Func<T1, T2> Map<T1, T2>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With