[非專業翻譯] Mapster - 資料型別

玩雙截棍的熊貓發表於2021-06-23

[非專業翻譯] Mapster - 資料型別

系列介紹

[非專業翻譯] 是對沒有中文文件進行翻譯的系列部落格,文章由機翻和譯者自己理解構成,和原文相比有所有不同,但意思基本一致。

因個人能力有限,如有謬誤之處還請指正,多多包涵。

正文

本文將說明 Mapster 中的 資料型別

基本型別

基本型別的轉換 ,例如: int/bool/dobule/decimal ,包括可空的基本型別。

只要C#支援型別轉換的型別,那麼在 Mapster 中也同樣支援轉換。

decimal i = 123.Adapt<decimal>(); //equal to (decimal)123;

列舉型別

Mapster 會自動把列舉對映到數字型別,同樣也支援 字串到列舉 和 列舉到字串的對映。

.NET 預設實現 列舉/字串 轉換非常慢,Mapster 比 .NET 的預設實現快兩倍。

在 Mapster 中,字串轉列舉,如果字串為空或空字串,那麼列舉將初始化為第一個列舉值。

在Mapster中,也支援標記的列舉。

var e = "Read, Write, Delete".Adapt<FileShare>();  
//FileShare.Read | FileShare.Write | FileShare.Delete

對於不同型別的列舉,Mapster 預設將值對映為列舉。呼叫 EnumMappingStrategy 方法可以指定列舉對映方式,如:

TypeAdapterConfig.GlobalSettings.Default
    .EnumMappingStrategy(EnumMappingStrategy.ByName);

字串型別

在 Mapster 中,將其它型別對映為字串時,Mapster 將呼叫型別的 ToString 方法。

如果將字串對映為型別時,Mapster 將呼叫型別的 Parse 方法。

var s = 123.Adapt<string>(); // 等同於: 123.ToString();
var i = "123".Adapt<int>();  // 等同於: int.Parse("123");

集合

包括列表、陣列、集合、包括各種介面的字典之間的對映: IList<T>, ICollection<T>, IEnumerable<T>, ISet<T>, IDictionary<TKey, TValue> 等等…

var list = db.Pocos.ToList();
var target = list.Adapt<IEnumerable<Dto>>();  

可對映物件

Mapster 可以使用以下規則對映兩個不同的物件

  • 源型別和目標型別屬性名稱相同。 例如: dest.Name = src.Name
  • 源型別有 GetXXXX 方法。例如: dest.Name = src.GetName()
  • 源型別屬性有子屬性,可以將子屬性的賦值給符合條件的目標型別屬性,例如: dest.ContactName = src.Contact.Namedest.Contact_Name = src.Contact.Name

示例:

class Staff {
    public string Name { get; set; }
    public int GetAge() { 
        return (DateTime.Now - this.BirthDate).TotalDays / 365.25; 
    }
    public Staff Supervisor { get; set; }
    ...
}

struct StaffDto {
    public string Name { get; set; }
    public int Age { get; set; }
    public string SupervisorName { get; set; }
}

var dto = staff.Adapt<StaffDto>();  
//dto.Name = staff.Name, dto.Age = staff.GetAge(), dto.SupervisorName = staff.Supervisor.Name

可對映物件型別包括:

  • 結構體
  • 介面
  • 實現 IDictionary<string, T> 介面的字典型別
  • Record 型別 (類、結構體、介面)

物件轉換為字典的例子:

var point = new { X = 2, Y = 3 };
var dict = point.Adapt<Dictionary<string, int>>();
dict["Y"].ShouldBe(3);

Record 型別的例子:

class Person {
    public string Name { get; }
    public int Age { get; }

    public Person(string name, int age) {
        this.Name = name;
        this.Age = age;
    }
}

var src = new { Name = "Mapster", Age = 3 };
var target = src.Adapt<Person>();

自動對映 Record 型別有一些限制:

  • Record 型別屬性必須沒有 set
  • 只有一個非空建構函式
  • 建構函式中的所有引數名稱必須與屬性名稱相同

如果不符合以上規則,需要增加額外的 MapToConstructor 配置

相關文章