2013-04-20 2 views
0

먼저 지저분한 제목에 대해 사과드립니다. 나는 그것을 어떻게 말로 표현할 지 잘 모르겠다. 그래서 나는 그 상황을 기술 할 것이다.특정 제네릭 유형의 클래스 속성이 제네릭 유형으로 캐스팅되어 메소드를 실행합니다.

나는 우리의 제품에 대한 비교 엔진을 쓰고, 그 다음과 같은 다양한 제품을 비교 할 수 : ComparableProduct, 재산

을 추가

public abstract class ComparableProduct 
{ 
    public ComparableProperty<decimal> Weight { get; set; } 
    public ComparableProperty<decimal> Width { get; set; } 
    public ComparableProperty<decimal> Height { get; set; } 
    public ComparableProperty<decimal> Depth { get; set; } 
    public bool IsBetterThan(ComparableProduct target){} 
} 

실제 제품은 같은 화면으로 ComparableProduct에서 파생 된

이것은 내가 ComparableProduct에서 파생 된 키보드, 스크린, StorageDevice ... 등 등의 속성을 가진 랩탑을 가질 수 있음을 의미합니다. 나는 그들이 작동해야 모든 논리에 의해, 이러한 테스트하지 않았습니다

public abstract class ComparableProperty<T> where T : IComparable<T> 
{ 
    T Value { get; set; } 
    public ComparisonType ComparisonType { get; set; } 
    public bool IsBetterThan(T target) 
    { 
     if(ComparisonType == ComparisonType.GreaterThan) 
      return Value.CompareTo(target) >= 0; 
     return Value.CompareTo(target) <= 0; 
    } 

    public bool IsBetterThan(IEnumerable<T> targets) 
    { 
     foreach(var target in targets) 
     { 
      if (ComparisonType == ComparisonType.SmallerThan && Value.CompareTo(target) >= 0) 
       return false; 
      if (ComparisonType == ComparisonType.GreaterThan && Value.CompareTo(target) <= 0) 
       return false; 
     } 
     return true; 
    } 

} 

:

이 같은 차례로 유사한 특성을 가지고있다. 내가 겪고있는 문제는 ComparableProduct의 IsBetterThan 메서드에 있습니다. 예상되는 기능은 최상위 클래스 (예 : 랩톱)에서 ComparableProduct 속성을 통해 반복되고 다른 복사본에 대해 IsBetterThan이라고 부르며 하위 속성을 통해 반복됩니다 ... 또한 모든 ComparableProduct ComparableProperty 속성은 IsBetterThan 다른 등급 '과 동등한 가치를 지닌다.

어쨌든, 여기에있는 것이 있습니다. 그리고 당신은 내가 가지고있는 문제를 볼 수 있습니다.

public bool IsBetterThan(ComparableProduct target) 
    { 
     foreach(var property in GetType().GetProperties().Where(x => x.PropertyType == typeof(ComparableProduct))) 
     { 
      var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as ComparableProduct; 
      var local = property.GetValue(this, null) as ComparableProduct; 
      if(local != null && !local.IsBetterThan(compareTo)) 
       return false; 
     } 
     foreach(var property in GetType().GetProperties().Where(x => x.PropertyType == typeof(ComparableProperty<>))) 
     { 
      var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as ComparableProperty<>; 
      var local = property.GetValue(this, null) as ComparableProperty<>; 
      if(local != null && !local.IsBetterThan(compareTo)) 
       return false; 
     } 
    } 

당신이 볼 수 있듯이

, 나는 그것이 제네릭 형식을 실종을 의미 ComparableProperty <>에 캐스팅하기 위해 노력하고있어. 그러나, 나는 관련 속성의 제네릭 타입을 얻는 방법을 잘 모르고있다.

더 좋은 방법이 있다면 ... 나는 할 수있는 모든 조언을 취할 것이지만, 이것은 내 마음에 온 첫 번째 절반 괜찮은 방법입니다.

편집 : 너무 빨리

말했다. 나는이 같은 ComparableProduct의 IsBetterThan의 속성을 열거 할 때 :

foreach(var property in GetType().GetProperties()) 
     { 
      var t = property.GetType().GetInterfaces(); 
      if (!property.GetType().GetInterfaces().Contains(typeof(IComparableProperty))) continue; 

      var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as IComparableProperty; 
      var local = property.GetValue(this, null) as IComparableProperty; 
      if (local == null) continue; 
      if(!local.IsBetterThan(compareTo)) 
       return false; 
     } 

를 그 다음은 인터페이스에 IComparableProperty을 찾을 수 없습니다 나타납니다. 내가 포함 할 수있는 주요 방법을 통해 갔지만 ... ICustomAttributeProvider, _MemberInfo, _PropertyInfo 및 ISerializable 만 인터페이스가 포함됩니다.

편집 2 :

나는

if (property.PropertyType.Name != "ComparableProperty`1") continue; 

에 문자열 비교에 다시 떨어지는 그리고 ComparableProperty과는 IEnumerable 전체 비교가 완벽하게 작동합니다>를 IEnumerable T를 변경 한 후이 문제를 해결했다.

답변

0

가 아닌 일반적인 인터페이스를 만든 다음 작업을 할 수 있습니다

public interface IComparableProperty 
    { 
     bool IsBetterThan(object target); 

     bool IsBetterThan(IEnumerable targets); 
    } 

    public abstract class ComparableProperty<T>: IComparableProperty where T : IComparable<T> 
    { 
     T Value { get; set; } 
     public ComparisonType ComparisonType { get; set; } 
     public bool IsBetterThan(T target) 
     { 
      if (ComparisonType == ComparisonType.GreaterThan) 
       return Value.CompareTo(target) >= 0; 
      return Value.CompareTo(target) <= 0; 
     } 

     public bool IsBetterThan(IEnumerable<T> targets) 
     { 
      foreach (var target in targets) 
      { 
       if (ComparisonType == ComparisonType.SmallerThan && Value.CompareTo(target) >= 0) 
        return false; 
       if (ComparisonType == ComparisonType.GreaterThan && Value.CompareTo(target) <= 0) 
        return false; 
      } 
      return true; 
     } 

     bool IComparableProperty.IsBetterThan(object target) 
     { 
      return IsBetterThan((T) target); 
     } 

     bool IComparableProperty.IsBetterThan(IEnumerable targets) 
     { 
      return IsBetterThan((IEnumerable<T>) (targets)); 
     } 
    } 

편집을 0 :

이 방법 Type.IsAssignableFrom (유형)를 사용하려고 했 이런 식으로 :

foreach (var property in GetType().GetProperties()) 
     { 
      if (!typeof(IComparableProperty).IsAssignableFrom(property.PropertyType)) continue; 

      var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as IComparableProperty; 
      var local = property.GetValue(this, null) as IComparableProperty; 
      if (local == null) continue; 
      return local.IsBetterThan(compareTo); 
     } 
+0

오, 이런, 나는 잠을 자지 못할 때 내 정보의 50 %를 잃는 것 같습니다. 이것은 실제로 해결책입니다, 감사합니다! – NeroS

+0

너무 빨리 말했습니다. 명확하게 OP를 수정했습니다. – NeroS

+0

맞아, 대답은 기술적으로 여전히 내 원래 질문을 해결 그래서 그것을 받아 들일 것입니다. 특정 인터페이스를 사용하면 트릭을 만들었지 만 강력한 타이핑을 사용하려면 한 부분을 알아 내야합니다. :) – NeroS

관련 문제