Function< T>用于特定的而不是泛型

本文关键字:泛型 用于 Function | 更新日期: 2023-09-27 18:14:21

我正在查看Automapper的源代码,但仍然无法获得我想要的信息。

我想把一个对象映射到两个不同的dto。

public class UserOrderDto {
    // common properties like UserId
    int OrderAmount { get; set; }
}
public class UserContactDto {
    // common properties like UserId
    string PhoneNumber { get; set; }
}

所以我有:

internal static UserOrderDto Map(User user) { ... }

现在我想要另一个映射,比如:

internal static UserContactDto Map(User user) { ... }

当然,这不起作用,因为Map是不明确的,所以我尝试使Map返回类型显式,如:

internal static UserOrderDto Map<UserOrderDto>(User user) { ... }
internal static UserContactDto Map<UserContactDto>(User user) { ... }

令我惊讶的是,这不起作用,所以我确定我得到了错误的<>语法。

,但这是:

internal static T Map<T>(User user) { ... }

我对返回T不感兴趣,我知道我想为每个方法返回一个特定的类型。

不使用反射和切换到泛型类型是否可能有这样的场景?

我知道我可以改变函数的名称,如MapToUserOrderDtoMapToUserContactDto,但我认为这对其他开发人员和我自己来说是丑陋的api,因为没有什么能阻止你做MapToPapafrita并返回Ketchup

我猜Automapper使用反射…(?)

Function< T>用于特定的而不是泛型

不行,你不能做你想做的事。

首先,函数不能仅仅基于返回类型重载。

你第一次尝试失败的原因,正如你指出的,是方法调用是模糊的。您使用相同的命名方法和相同的参数,唯一的区别是返回类型。这在c#中是不允许的:你需要做一些其他的事情来区分签名。

一个解决方案是使方法泛型,这允许泛型类型参数成为鉴别符。但是使方法泛型需要在签名中有一个泛型类型参数。这就是您第二次尝试失败的原因:您没有在签名中包含任何未绑定类型参数。

对于泛型方法,您可以在调用位置指定具体类型,而不是在方法定义中。换句话说,您可以使用以下语法调用这个方法:
var dto = Map<User2Dto>(user);

这个呢:

public class User
{
    public User(string id) { this.ID=id; }
    public string ID
    {
        get;
        private set;
    }
}
public interface IUserDto
{
    public string UserID { get; }
    public void SetUser(User user);
}
public class UserOrderDto : IUserDto
{
    public string UserID { get; private set; }
    public void SetUser(User user) { UserID=user.ID; }
    int OrderAmount { get; set; }
}
public class UserContactDto : IUserDto
{
    public string UserID { get; private set; }
    public void SetUser(User user) { UserID=user.ID; }
    string PhoneNumber { get; set; }
}
class Program
{
    internal static T Map<T>(User user) where T : IUserDto, new()
    {
        T map=new T();
        map.SetUser(user);
        return map;
    }
    static void Main(string[] args)
    {
        var user=new User("Mary");
        var map=Map<UserContactDto>(user);
    }
}