[英]Mapping generic properties with reflection / Cast property to a generic type
我正在使用反射将DTO(xSearchQuery)的一个类(xSearchObject)映射(设置属性)。 我已尝试减少代码量,以便更轻松地查看要实现的目标。 我无法更改SearchField
,但可以更改DTOSearchField
。
DTOSearchField<T>
属性。 SearchField<T>
属性。 源类属性类型
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
}
映射:(基于轻量级对象到对象映射器 )如果我有一个通用的DTOSearchField<T>
而不是例如StringDTOSearchField
, IntDTOSearchField
等类并将其StringDTOSearchField
IntDTOSearchField
为StringDTOSearchField
,则我可以非常愉快地进行映射。 因此,对于每个源属性:
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
是DTOSearchField<T>
, destinationProperty
是SearchField<T>
,并且它们都具有类型T的属性,因此,如果在运行时之前不知道T是什么,就好像没关系。
我知道强制转换将无法正常工作,因为T直到运行时才知道。 除了每种可能类型的If-Then-Else之外,还有什么可以实现我想要的东西吗? 如果必须这样做,似乎无法使用泛型的优势。
谢谢,
您可以通过反射来调用WhereEquals方法,但是我建议按如下所述利用泛型,以发挥您的优势(因为您可以更改DTOSearchField):
public interface IDTOSearchField
{
void MapToSearchField(ISearchField searchField);
}
public class DTOSearchField<T> : IDTOSearchField
{
public T EqualTo;
public void MapToSearchField(ISearchField searchField)
{
if (!(searchField is SearchField<T>))
{
throw new ArgumentException("SearchField must be of type " + typeof(T).FullName + ".", "searchField");
}
((SearchField<T>)searchField).WhereEquals(EqualTo);
}
}
然后,您可以在界面上使用此新方法进行映射,如下所示:
public void MapField(IDTOSearchField source, ISearchField destination)
{
source.MapToSearchField(destination);
}
如果您不想让DTOSearchField类对SearchField类有所了解,可以采用一些解决方法,但这对于此答案来说是太多讨论了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.