我正在使用反射从 DTO(xSearchQuery)映射(设置属性)到一个类(xSearchObject)。我试图减少代码,以便更容易看到我想要实现的目标。我不能改变SearchField
,但我可以改变DTOSearchField
。
- 源类有n个类型的属性
DTOSearchField<T>
。 - 目标类有n个类型的属性
SearchField<T>
。 - Source 和 Destination 具有相同数量的同名属性。
源类属性类型
public class DTOSearchField<T> : IDTOSearchField
{
public T EqualTo;
}
目的地类属性类型:
public class SearchField<T> : ISearchField
{
public void WhereEquals(T value)
{
_clauses.Add(_name + " = " + Converter.ConvertValueToSql(value));
}
// etc
}
映射:(基于Lightweight Object to Object Mapper)我可以很高兴地进行映射,而不是DTOSearchField<T>
我拥有的泛型,例如,StringDTOSearchField
等IntDTOSearchField
类并转换为那些。所以对于每个源属性:
if (sourceVal.GetType().IsAssignableFrom(typeof(StringDTOSearchField)))
{
var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<string>;
var sourceStringField = sourceVal as StringSearchField;
if (sourceStringField != null)
{
if (!string.IsNullOrEmpty(sourceStringField.EqualTo)) destinationProperty.WhereEquals(sourceStringField.EqualTo);
}
}
else if (sourceVal.GetType().IsAssignableFrom(typeof(IntDTOSearchField)))
{
// Etc
}
或者我可以保留通用DTOSearchField<T>
并基于以下内容执行大量 If-Then-elses:
Type t = sourceVal.GetType().GetGenericArguments()[0];
转换为适当的类型,
但我觉得我应该能够做类似的事情:
Type t = sourceVal.GetType().GetGenericArguments()[0];
var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<t>;
destinationProperty.WhereEquals(sourceVal.EqualTo.Value);
因为sourceVal
is aDTOSearchField<T>
和destinationProperty
is a SearchField<T>
,并且它们都具有 T 类型的属性,所以感觉如果您在运行时之前不知道 T 是什么,这并不重要。
我知道演员表不会起作用,因为 T 直到运行时才知道。除了针对每种可能类型的 If-Then-Else 之外,还有什么方法可以实现我想要的吗?如果我必须这样做,它似乎会破坏使用泛型的优势。
谢谢,