簡體   English   中英

生成要傳遞的方法和參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM