7

I want to map my objects with generic extension methods.

public class Customer    
{    
    public string FirstName { get; set; }    
    public string LastName { get; set; }    
    public string Email { get; set; }    
    public Address HomeAddress { get; set; }    
    public string GetFullName()    
    {  
        return string.Format(“{0} {1}”, FirstName, LastName);
    }    
}

And this is viewmodel

public class CustomerListViewModel    
{    
    public string FullName { get; set; }
    public string Email { get; set; }    
    public string HomeAddressCountry { get; set; }    
}

So I am creating map, Mapper.CreateMap<Customer, CustomerListViewModel>();

And I want to create an extension method

public static class MapperHelper
{
    public static CustomerListViewModel ToViewModel(this Customer cust)
    {
        return AutoMapper.Mapper.Map<Customer, CustomerListViewModel>(cust);
    }
}

But I want to make generic this helper:

public static class MapperHelper<TSource, TDest>
{
    public static TDest ToViewModel(this TSource cust)
    {
        return AutoMapper.Mapper.Map<TSource, TDest>(cust);
    }
}

Gives error: Extension method can only be declared in non-generic, non-nested static class

If I can not make generic, I should create helper class for all mapping. Is there any way to solution?

barteloma
  • 6,403
  • 14
  • 79
  • 173
  • possible duplicate of [Why is it impossible to declare extension methods in a generic static class?](http://stackoverflow.com/questions/2618271/why-is-it-impossible-to-declare-extension-methods-in-a-generic-static-class) – Iain Galloway Apr 22 '15 at 11:11
  • also:- http://stackoverflow.com/questions/3930335/why-are-extension-methods-only-allowed-in-non-nested-non-generic-static-class – Iain Galloway Apr 22 '15 at 11:12
  • Yes, by just doing what the compile error tells you *Extension method can only be declared in non-generic, non-nested static class*, so move the generic arguments to your method instead to the class... –  Apr 22 '15 at 11:22

3 Answers3

11

Even better than these solutions is to use the non-generic Map method:

public static class MapperHelper
{
    public static TDest MapTo<TDest>(this object src)
    {
        return (TDest)AutoMapper.Mapper.Map(src, src.GetType(), typeof(TDest));
    }
}

In your code:

var model = customter.MapTo<CustomerViewModel>();

Now you don't need the superfluous Source type in your generic method.

Amr Elgarhy
  • 66,568
  • 69
  • 184
  • 301
Jimmy Bogard
  • 26,045
  • 5
  • 74
  • 69
  • Give me a error on .net 6: "An object reference is required for the non-static field, method, or property 'Mapper.Map(object, Type, Type)'" – Gabriel Simas Feb 01 '22 at 16:16
3

Can't you just do this?:

public static class MapperHelper
{
    public static TDest ToViewModel<TSource, TDest>(this TSource cust)
    {
       return AutoMapper.Mapper.Map<TSource, TDest>(cust);
    }
}
hal
  • 1,705
  • 1
  • 22
  • 28
Arion
  • 31,011
  • 10
  • 70
  • 88
  • No because the 1st generic argument can't be implicitly inferred. http://stackoverflow.com/questions/9822723/generic-extension-method-for-automapper/15350813 – Ravi Kumar Mistry Feb 01 '17 at 18:25
1

You can't define extension methods in a generic class because there would be no way for you to specify the type parameters when you invoke it!

public static class MapperHelper<TSource, TTarget>
{
  public static TTarget ToViewModel(this TSource source)
  {
    ...
  }
}

...

// this is no problem if we invoke our method like a
// static method:-
var viewModel = MapperHelper<MyModel, MyViewModel>.ToViewModel(model);

// but if we use the extension method syntax then how
// does the compiler know what TSource and TTarget are?:-
var viewModel = model.ToViewModel();

You have to make the method generic instead:-

public static class MapperHelper
{
  public static TTarget ToViewModel<TSource, TTarget>(this TSource source)
  {
    ...
  }
}

...

var viewModel = model.ToViewModel<MyModel, MyViewModel>();
Iain Galloway
  • 18,669
  • 6
  • 52
  • 73