我正在尝试学习泛型并在以下代码中实现它。我是这个概念的新手,所以它可能不是最好的方法,所以我对任何事情持开放态度。
我有一个方法,它接受一个类并将其映射到一个新类的对象并返回:
public OtherClass CreateNeed(long id, string name, int needTypeId)
{
var newDto = new OtherClass();
newDto.Id = id;
newDto.Name = name;
newDto.NeedTypeId = needTypeId;
return newDtoToAdd;
}
这就是我所说的:
var needClass = new NeedClass();
var addedNeed = CreateNeed(needClass.id, needClass.name, needClass.needTypeId);
但有时,我需要映射的对象是相同的OtherClass ...所以我这样称呼..
var otherClass = new OtherClass();
var otherAddedNeed = CreateNeed(otherClass.id, otherClass.name, otherClass.needTypeId);
我想将它作为泛型类型传递,因此CreateNeed方法可以处理这两种类型......可能是这样的:
var needClass = new NeedClass();
var addedNeed = CreateNeed<NeedClass>(needClass);
var otherClass = new OtherClass();
var addedNeed = CreateNeed<OtherClass>(otherClass);
我发现自己经常在我的代码中遇到这种问题,并且只需要传入部分类来修改,但返回总是返回相同类型的对象。我也试图一般地学习泛型,那么如何修改方法以及随后的调用进行泛化?
答案 0 :(得分:1)
选项很少。首先,您根本不需要通用方法来实现这一目标。当然,你可以用泛型来做到这一点,但不一定。
第一个选项,您创建一个接口以匹配两个类结构,并让非泛型方法接受此接口作为参数。
//Implement this interface with your 2 classes
public interface IClass
{
int Id {get;set;}
//other fields here.
}
public interface OtherClass : IClass
{
public int Id {get;set;}
//other fields here.
}
public interface NeedClass : IClass
{
public int Id {get;set;}
//other fields here.
}
public OtherClass CreateNeed(IClass input)
{
var newDto = new OtherClass();
newDto.Id = input.id;
newDto.Name = input.name;
newDto.NeedTypeId = input.needTypeId;
return newDtoToAdd;
}
//example call
var newNeedClass = new NeedClass();
//set all your properties here.
newNeedClass.Id =1;
var otherClassInstance = CreateNeed(newNeedClass );
第二个,将参数类型设为dynamic
。我建议不要这样做。
thrid one ,如果您热衷于使用泛型,那么
public OtherClass CreateNeed<T>(T inp) where T: IClass
{
var newDto = new OtherClass();
newDto.Id = inp.id;
newDto.Name = inp.name;
newDto.NeedTypeId = inp.needTypeId;
return newDtoToAdd;
}
然后您可以使用以下语法
来调用它var newNeedClass = new NeedClass();
//set all your properties here.
newNeedClass.Id =1;
var otherClassInstance = CreateNeed(newNeedClass );
最后,您还可以使用 Automapper 等映射库来简化映射。但是,是的,这会产生对第三方框架的依赖。
答案 1 :(得分:1)
解决方案是定义具有所需属性的接口:
public interface IConvertable
{
int id { get; set; }
string name { get; set; }
//...
}
在要转换为彼此的所有类中实现接口。通用方法是:
public static T CreateNeed<T>(IConvertable ToConvert) where T : IConvertable, new()
{
T Need = new T();
Need.id = ToConvert.id;
Need.name = ToConvert.name;
//...
return Need;
}
现在可以将实现IConvertable接口的所有类转换为实现IConvertable接口的其他类(请注意,构造函数不允许使用此实现的任何参数)。用法示例:
OtherClass OldObject = new OtherClass() { id = 1, name = "test" };
NeededClass NewObject = CreateNeed<NeededClass>(OldObject);
答案 2 :(得分:1)
你也可以像这样创建mapper类:
public class Mapper
{
public static TOutput Map<TInput, TOutput>(TInput input, Action<TInput, TOutput> mapFunc)
where TOutput : class, new()
{
TOutput t = new TOutput();
mapFunc(input, t);
return t;
}
}
然后用它来表示类之间的映射:
NeedClass c = new NeedClass { Id = 1, Name = "Name" };
OtherClass oc = Mapper.Map<NeedClass, OtherClass>(c, (input, output) =>
{
output.Id = input.Id;
output.Name = input.Name;
});
然后定义默认的映射器函数以定期使用它,对于要部分映射的情况,请按照Action<TInput, TOutput>
进行映射。
要明确现实生活场景,您不想创建这类映射器,而是使用AutoMapper代替。祝你好运。