如何将2个泛型类型传递给扩展方法

时间:2014-05-09 04:12:38

标签: c# generics extension-methods

我创建了以下扩展方法

public static T Map<TEntity,T>(this TEntity entity) where TEntity : IEntity
{
    return Mapper.Map<TEntity, T>(entity);        
}

这允许以下

Db.ExchangeSets.FirstOrDefault().Map<ExchangeSet, ExchangeSetSimpleViewModel>()

但是我想知道是否有我可以修改扩展方法,所以我可以调用如下的短路版本

Db.ExchangeSets.FirstOrDefault().Map<ExchangeSetSimpleViewModel>()

请注意:

是否应该像这样使用automapper不在问题的范围内,它更像是一个事实发现任务

<小时/> 的更新

对于那些在家里玩的人,在scotts评论的帮助下,我设法在Generic extension method for automapper找到了上述功能的额外解决方案

public static T Map<T>(this IEntity entity) 
{
    return (T)Mapper.Map(entity, entity.GetType(), typeof(T));  
}

除了AutoMapper之外,这不是实际问题的答案,而是相应地标记

3 个答案:

答案 0 :(得分:2)

如果您想知道为什么这是不可能的,我认为问题在于含糊不清:

public static T Map<TEntity,T>(this TEntity entity) where TEntity : IEntity
{
    return Mapper.Map<TEntity, T>(entity);        
}

public static T Map<T>(this ExchangeSet set)
{
    // ...
}

那么,调用哪种方法?请记住,这只是一个简单的例子。很有可能未来可以实现部分类型推断,但我认为在重载解决方案中它太混乱,成本/收益将完全失控。然后,这只是猜测。

答案 1 :(得分:1)

您所要求的是不可能的。调用泛型方法时,要么所有泛型类型参数都必须从输入中输入,要么必须明确指定它们。您的方法只有一个输入,因此您无法推断出两个泛型类型参数,因此必须始终明确指定它们。您建议的代码意味着该方法只有一个泛型类型参数,这将使它成为一种不同的方法。

答案 2 :(得分:1)

如果引入第二个(链式)函数调用,则可以实现此目的:

Db.ExchangeSets.FirstOrDefault().Map().To<ExchangeSetSimpleViewModel>()

推断的通用参数是一种全有或全无的交易;如果没有足够的&#34;实际&#34;传递给方法的参数用于编译器计算所有通用参数,编译器强制您手动指定每个通用参数。

为了能够使用上面的代码片段,您需要使用一个(唯一的)推断的泛型参数进行一次方法调用,并使用一个手动指定的泛型参数进行一次方法调用。

To<>方法可以像这样实现:

public static MapExtensionHelper<TEntity> Map<TEntity>(this TEntity entity) where TEntity : IEntity
{
    return new MapExtensionHelper<TEntity>(entity);        
}

public class MapExtensionHelper<TEntity> where TEntity : IEntity
{
    public MapExtensionHelper(TEntity entity)
    {
        _entity = entity;
    }

    private readonly TEntity _entity;

    public T To<T>()
    {
        return Mapper.Map<TEntity, T>(_entity);
    }
}