简体   繁体   中英

Eliminating inferrable generic type parameters from extension methods

I am using .NET mapping library AutoMapper in my application, and I have a generic extension method like this:

public static T2 Map<T1, T2>(this T1 o)
{
    return Mapper.Map<T1, T2>(o);
}

...

var nc = new NonCustomer();
Customer c = nc.Map<NonCustomer, Customer>();

Is there any way I can get rid of the T1 generic parameter from the extension method so it is inferred? Resulting in a call like this:

var nc = new NonCustomer();
Customer c = nc.Map<Customer>();

No, there is no way. Generic type inference doesn't work on return types. This kind of puts the usefulness of your extension method questionable. Why not directly working with the .Map<TSource, TDest> method?

You do not need to use generic version for T1 parameter.

You just need to change it to object:

public static TDest Map<TDest>(this object o)
{
    // todo check o is not null
    return (TDest) Mapper.Map(o, o.GetType(), typeof (TDest));
}

If you are using AutoMapper v2 and above, you could write it as following:

public static TDest Map<TDest>(this object o)
{
    return Mapper.Map<TDest>(o);
}

Great question. I've always been too lazy to answer it for myself but then the cobbler's children always get extension methods last...

You could make it a bit DRYer and arguably a touch prettier by side stepping the issue and doing one inference at a time:

public static MapperSource<T> Mapper(this T that)
{
    return new MapperSource<T>( that);
}

public class MapperSource<T>
{
    public T2 To<T2>
    {
        return Mapper.Map<T,T2>();
    }
}

Which allows you to:

var nc = new NonCustomer();
Customer c = nc.Mapper().To<Customer>();

A more common way (for me anyway) to consume those is to set up helpers for each Mapper.CreateMap 'd route as follows:

public static Customer ToResult(this NonCustomer that)
{
    return that.Mapper().To<Customer>();
}

(Sadly because there are no Extension Properties, it can't get any prettier than this. Then again, it'll all be moot when we're all using F#)

不,你不能,因为在c#中没有部分类型推断这样的东西。

Only when you remove the T1 generic type altogether and write a specific method for NonCustomer :

public static T2 Map<T2>(this NonCustomer o)
{
    return Mapper.Map<NonCustomer, T2>(o);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM