简体   繁体   中英

Generic extension method refactor

I'm wondering if the following can be refactored in the way I would like it:

[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListExtensions
{
    public static PaginatedList<Y> ToMappedPaginatedList<T, Y>(this PaginatedList<T> source)
    {
        var mappedList = new List<Y>();
        Mapper.Map(source, mappedList);

        return new PaginatedList<Y>(mappedList, source.PageIndex, source.PageSize, source.TotalCount);
    }
}

The Mapper.Map line is using AutoMapper to map properties from an entity to a DTO object.

This is called like this:

var list = await _service.GetAllAsync(pageIndex, _pageSize);
var dtoList = list.ToMappedPaginatedList<Farmer, FarmerDTO>();

but I'd like to call it like this:

var dtoList = list.ToMappedPaginatedList<FarmerDTO>();

This saves a little bit of typing and you don't always need to be aware of the source list its type. Unfortunately this code doesn't work and I'm not sure if there's a simple answer.

Anyone got an idea?

Thanks in advance.

Yannick

Either you call a method and specify all the generic arguments or you specify none and let the compiler infer them, there's no support for partial inference.

As such, the only way to get your code to compile is to make ToMappedPaginatedList take 1 generic parameter, instead of two.

If you have access to the PaginatedList class, putting the method in there will enable the syntax you desire since the instance knows what it's own type is.

I don't recommend the following but it demonstrates a way to take advantage of type inference.

You can enable type inference by adding a 2nd "useless" parameter of type Y. If you pass default(FarmerDTO) as the 2nd parameter, a null will be passed as the parameter value but the intended type will be inferred.

[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListExtensions
{
    public static PaginatedList<Y> ToMappedPaginatedList<T, Y>(this PaginatedList<T> source, Y destinationPlaceholder)
    {
        var mappedList = new List<Y>();
        Mapper.Map(source, mappedList);

        return new PaginatedList<Y>(mappedList, source.PageIndex, source.PageSize, source.TotalCount);
    }
}

Call it like this:

var result1 = s.ToMappedPaginatedList(default(FarmerDTO));

Fair warning. I've never used this because I find the resulting code to be non-obvious as to what it is doing.

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