[英]Exact type constraints in generic types - C#
我想實現一個泛型類型映射器,我正在努力解決與泛型類型約束相關的問題。
我有和實體映射器類定義如下:
public class EntityMapper<TDto, TEntity>
{
public void RegisterMapping<TDtoProperty, TEntityProperty>(
Expression<Func<TDto, TDtoProperty>> expressionFrom,
Expression<Func<TEntity, TEntityProperty>> expressionTo,
Func<TDtoProperty, TEntityProperty> mapper)
{
// mapping
}
}
我還有2個類我要映射的屬性:
public class Foo
{
public long FooLongProp { get; set; }
public decimal? FooDecimalNullProp { get; set; }
public string FooStringProp { get; set; }
}
public class Bar
{
public long? BarLongNullProp { get; set; }
public decimal BarDecimalProp { get; set; }
}
映射正在執行如下:
public void Map()
{
var mapper = new EntityMapper<Foo, Bar>();
mapper.RegisterMapping(x => x.FooLongProp, x => x.BarLongNullProp, x => x); // FooLongProp -> long, BarLongNullProp -> long?
mapper.RegisterMapping(x => x.FooDecimalNullProp, x => x.BarLongNullProp, x => x); // FooDecimalNullProp -> decimal?, BarLongNullProp -> long?
mapper.RegisterMapping(x => x.FooDecimalNullProp, x => x.BarDecimalProp, x => x); // FooDecimalNullProp -> decimal?, BarDecimalProp -> decimal
mapper.RegisterMapping(x => x.FooStringProp, x => x.BarLongNullProp, x => x); // FooStringProp -> string, BarLongNullProp -> long?
}
我希望RegisterMapping
的第三個參數返回與TEntityProperty
完全相同的類型。 不幸的是編譯器沒有報告long -> long?
之間的映射代碼long -> long?
以下是一個錯誤。 它甚至不報告錯誤映射decimal? -> decimal
decimal? -> decimal
(將在運行時中斷)。
編譯器報告錯誤的唯一地方是我想要轉換string -> decimal?
。
所以我有以下問題:
任何其他建議,歡迎評論。
mapper.RegisterMapping(x => x.FooLongProp, x => x.BarLongNullProp, x => x); // FooLongProp -> long, BarLongNullProp -> long?
x => x.FooLongProp
編譯器推斷( Expression<Func<Foo, long>>
) x => x.BarLongNullProp
編譯器推斷( Expression<Func<Bar, long?>>
) x => x
編譯器推斷( Func<long, long?>>
) mapper.RegisterMapping(x => x.FooDecimalNullProp, x => x.BarLongNullProp, x => x); // FooDecimalNullProp -> decimal?, BarLongNullProp -> long?
x => x.FooDecimalNullProp
編譯器推斷( Expression<Func<Foo, decimal?>>
)
x => x
編譯器推斷( Func<decimal?, decimal?>>
)!! 為什么?? 因為x=>x
是Func<type of x,type of x>
x => x.BarLongNullProp
編譯器推斷( Expression<Func<Bar, decimal?>>
)!! 為什么? 因為2號線它翻了long?
decimal?
所以它可以匹配通用參數。
在其他情況下發生類似的事情。 在最后一種情況下,編譯器查找Func<string, long?>
。 當你提供x=>x
( Func<string,string>
)時,編譯器無法推斷出你的泛型類型的正確類型,因此它會失敗。 將鼠標光標懸停在方法調用上將顯示編譯器推斷的泛型參數。 也許你應該為你的lambdas指定一個顯式的輸入。
mapper.RegisterMapping(x => x.FooLongProp, x => x.BarLongNullProp, x => x);
mapper.RegisterMapping(x => x.FooDecimalNullProp, x => x.BarLongNullProp, x => (long?)x);
mapper.RegisterMapping(x => x.FooDecimalNullProp, x => x.BarDecimalProp, x => (decimal)x);
mapper.RegisterMapping(x => x.FooStringProp, x => x.BarLongNullProp, x => (long?)(object)x ); //or any lambda which returns long?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.