2012-10-02 2 views
2

DTO (xSearchQuery)의 한 클래스 (xSearchObject)에서 리플렉션을 사용하여 속성을 매핑합니다 (속성 설정). 나는 달성하려는 것을 쉽게 볼 수 있도록 코드를 줄이려고 노력했다. SearchField을 변경할 수 없지만 DTOSearchField을 변경할 수 있습니다.리플렉션/캐스팅 속성을 사용하여 일반 속성을 제네릭 유형으로 매핑

  • 소스 클래스 타입 DTOSearchField<T>N 특성을 갖는다.
  • 대상 클래스에는 SearchField<T> 유형의 n 속성이 있습니다.
  • 원본 및 대상의 이름이 인 동일한 번호의 속성이 있습니다.

소스 클래스 부동산 유형

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 기준) 나는 아주 행복하게 매핑을 수행 할 수 있습니다 일반대신에예를 들어 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-그런-를 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); 

: 내가 좋아하는 뭔가를 할 수있을 것 같은

는하지만 느낌은 DTOSearchField<T>이고 destinationPropertySearchField<T>이고 두 유형 모두 T 유형의 특성을 갖습니다. 런타임까지 T가 무엇인지 모르는 경우 중요하지 않습니다.

런타임까지 T를 알 수 없으므로 캐스트가 작동하지 않는다고 생각합니다. 가능한 모든 유형에 대해 If-Then-Else 이외의 원하는 것을 성취 할 수 있습니까? 필자가해야한다면 generics 사용의 이점을 무력화시키는 것 같다.

감사합니다,

답변

0

당신은 단지 방법 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 클래스에 대한 지식을 갖게하고 싶지 않다면이 문제를 해결할 수있는 방법이 있지만이 답변에 대해서는 너무 많은 토론입니다.

관련 문제