[英]How can I get the generic type parameter of the 'this' parameter in an extension method?
I'm trying to convert the following method to an extension method on IEnumerable: 我正在尝试将以下方法转换为IEnumerable上的扩展方法:
private static IEnumerable<TTarget> MapList<TSource, TTarget>(IEnumerable<TSource> source)
{
return source.Select(
element =>
_mapper.Map<TSource, TTarget>(element)
).ToList();
}
Right now it's called like this: 现在它被称为这样:
var sourceList = new List<SourceType>();
return MapList<SourceType, TargetType>(sourceList);
But I want to call it like this: 但我想这样称呼它:
var sourceList = new List<SourceType>();
return sourceList.MapTo<TargetType>();
I have tried doing this: 我试过这样做:
public static IEnumerable<TTarget> MapTo<TTarget>(this IEnumerable<TSource> source)
{
return source.Select(
element =>
Mapper.Map<TSource, TTarget>(element)
).ToList();
}
But I get type or namespace TSource
not found since it's not included in the method's type parameter list. 但是我找不到类型或名称空间
TSource
因为它没有包含在方法的类型参数列表中。 I can make it work like this: 我可以让它像这样工作:
public static IEnumerable<TTarget> MapTo<TSource, TTarget>(this IEnumerable<TSource> source)
{
return source.Select(
element =>
Mapper.Map<TSource, TTarget>(element)
).ToList();
}
But this I have to call it like this: 但是我必须这样称呼它:
var sourceList = new List<SourceType>();
sourceList.MapTo<SourceType, TargetType>();
Which I feel is not as clear as sourceList.MapTo<TargetType>()
. 我觉得它不像
sourceList.MapTo<TargetType>()
那样清晰。
Is there any way to do what I want? 有什么办法可以做我想要的吗?
There's not enough information in the call to fully determine the generic type parameters to pass to MapTo
, and C# doesn't support inferring only some of the types. 调用中没有足够的信息来完全确定传递给
MapTo
的泛型类型参数,而C#不支持仅推断某些类型。 You either have to specify all the types or none of them. 您必须指定所有类型或不指定任何类型。
However, you can get around this by redesigning your interface. 但是,您可以通过重新设计界面来解决这个问题。 Here's just one solution:
这只是一个解决方案:
public sealed class Mappable<TSource>
{
private readonly IEnumerable<TSource> source;
public Mappable(IEnumerable<TSource> source)
{
this.source = source;
}
public IEnumerable<TTarget> To<TTarget>()
{
return source.Select(
element =>
Mapper.Map<TSource, TTarget>(element)
).ToList();
}
}
public static class Extensions
{
public static Mappable<TSource> Map<TSource>(this IEnumerable<TSource> source)
{
return new Mappable<TSource>(source);
}
}
And now you can call it like this: 现在你可以这样称呼它:
var sourceList = new List<SourceType>();
var target = sourceList.Map().To<TargetType>();
Alternatively, if you give up on using extension methods, you can do it like this: 或者,如果您放弃使用扩展方法,您可以这样做:
public static class MapTo<TTarget>
{
public static IEnumerable<TTarget> From<TSource>(IEnumerable<TSource> source)
{
return source.Select(
element =>
Mapper.Map<TSource, TTarget>(element)
).ToList();
}
}
And call it like this: 并称之为:
var sourceList = new List<SourceType>();
var target = MapTo<TargetType>.From(sourceList);
Neither of these are particularly elegant. 这些都不是特别优雅。 It's up to you if you prefer this syntax over fully specifying the generic parameters on each call.
如果您更喜欢这种语法而不是完全指定每次调用的通用参数,则由您决定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.