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不感兴趣,我知道我想为每个方法返回一个特定的类型。
不使用反射和切换到泛型类型是否可能有这样的场景?
我知道我可以改变函数的名称,如MapToUserOrderDto
和MapToUserContactDto
,但我认为这对其他开发人员和我自己来说是丑陋的api,因为没有什么能阻止你做MapToPapafrita
并返回Ketchup
。
我猜Automapper
使用反射…(?)
不行,你不能做你想做的事。
首先,函数不能仅仅基于返回类型重载。
你第一次尝试失败的原因,正如你指出的,是方法调用是模糊的。您使用相同的命名方法和相同的参数,唯一的区别是返回类型。这在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);
}
}