[英]Genericizing a method and a parameter to be passed
我正在嘗試學習泛型並在以下代碼中實現它。 我是這個概念的新手,所以它可能不是最好的方法,因此我願意接受任何東西。
我有一個方法,該方法接受一個類並將其映射到新類的對象並返回:
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);
我發現自己的代碼中經常遇到這種問題,只需要傳入部分類進行修改,但是return總是返回相同類型的對象。 我也在嘗試一般性地學習泛型,那么如何修改要泛化的方法和后續調用 ?
沒有什么選擇。 首先,您根本不需要通用方法即可實現此目的。 當然,您可以使用泛型來執行此操作,但不必這樣做。
第一個選項 ,創建一個接口以匹配兩個類結構,並讓非泛型方法將此接口作為參數。
//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
。 我建議反對這種方法。
第三 ,如果您熱衷於使用泛型,那么
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之類的映射庫,使映射更容易。 但是,是的,它與第三方框架產生了依賴性。
一種解決方案是用所需的屬性定義一個接口:
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);
您也可以像這樣創建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 。 祝好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.