2014-11-04 2 views
1
에 같음

나는 사람들이 다른 사람들을보기 위해 querystring을 변경 중지하는 데 사용하려고 다음과 같은 방법을 자세히 설명했다 :재정이 IEquatable

public static bool IsCurrentUserAuthorisedVessel(HttpRequest request) 
{ 
    Guid currentUser = GetCurrentUserId(); 
    PersonRepository repo = new PersonRepository(); 
    VesselRepository vesselRepo = new VesselRepository(); 

    Person currentPerson = repo.GetPersonByUser(currentUser); 
    int qs = int.Parse(request.QueryString["VesselId"]); 
    Vessel currentVessel = vesselRepo.GetVessel(qs); 

    if (!String.IsNullOrEmpty(request.QueryString["VesselId"])) 
    {  
     if (IsCurrentUserAdmin()) 
     { 
      return true; //Always return true for admin     
     } 
     else 
     { 
      if (currentPerson.Vessels.Contains(currentVessel)) 
      { 
       return true; 
      } 
      else 
       return false; 
     }     
    } 
    return true; 
} 

을 나는 현재 currentPerson.Vessels 수익률 3 개 혈관을 디버깅하고 예에서 Icollection<Vessel> 중 하나는 VesselId 인 6을 가지며이 역시 역시 currentVessel의 VesselId가됩니다. 그러나 일치가 실패하고 메서드가 false을 반환합니다.

ICollection 내에서 ID가 6 인 선박이 currentVessel의 다른 인스턴스이기 때문에 비슷한 질문과 MSDN 설명서에 대한 일부 내용을 읽었습니다. 여기서 무슨 일이 일어나고 있는지 이해하고 있습니다. 참조가 동일하지 않게되고 평등 규칙과 관련이있는 것은 ID를 기반으로하지 않습니다.

Person 모델이 내 Vessel 모델에 IEquatable 인터페이스를 구현하고 Equals 메서드를 오버라이드 (override) 할 필요가 있음을 의미 하는가 public virtual ICollection<Vessel> Vessels { get; set; }가 포함되어 있습니다.

나는이 인스턴스에서 동일성에 대한 ID를 기반으로 사용자 정의 규칙을 원합니다. 이 방법을 어떻게 재정의합니까? 이 상황에서 Equals 재정

+0

사용중인 ORM (Entity Framework, NHibernate 등)의 태그를 추가하십시오. –

답변

3

이유는 단지 @ 제임스에 의해 제안 솔루션이 아닌

currentPerson.Vessels.Any(x => x.ID == currentVessel.ID) 
+0

고마워,하지만 바보처럼 느껴진다. 어떻게하면 쉽게 알 수 있습니다! – JsonStatham

1

변화

if (currentPerson.Vessels.Contains(currentVessel)) 
{ 
    return true; 
} 
else 
    return false; 

return currentPerson.Vessels.Any(x => x.ID == currentVessel.ID) 
2

에하지, 과잉 여기에 조금 보인다 모범 사례. 여기에 왜 Hashset<Vessel>에 추가되어야하는 혈관 목록이 많은 경우 GetHashCode에 색인이 생성되기 때문에 O(1)에만 비용이 부과되지만 .Any은 모든 요소를 ​​반복하여 찾아야 만 확장 방법을 사용해야하며 나는 역이 왜이

public class Vessel : IEquatable<Vessel> 
    { 
     public int Id { get; set; } 

     public bool Equals(Vessel other) 
     { 
      return Id == other.Id ; 
     } 

     public override int GetHashCode() 
     { 
      return Id; 
     } 
     public override bool Equals(object obj) 
     { 
      var vessel = obj as Vessel; 
      return vessel != null && vessel.Id == this.Id; 
     } 
    } 

업데이트처럼

이유를 뭔가를 할 수 O(n)

비용이 될 것입니다 예를 들어 List<T>과 같이 많은 Generics 컬렉션으로 변환 될 수있는 ICollection<Vessel>을 가지고 있다고 OP가 명시한 것이 가장 좋은 방법은 아닙니다. 일반적인 수집 객체의 수의 검색 방법이라고 MSDN

에서

. 이러한 유형 및 메서드 중 일부는 다음과 같습니다.

  • BinarySearch 메서드의 일반적인 오버로드 중 일부는 다음과 같습니다.
  • List.Contains (T), List.IndexOf, List.LastIndexOf 및 List.Remove를 포함하여 List 클래스의 검색 방법입니다.
  • ContainsKey 및 Remove를 비롯한 Dictionary 클래스의 검색 방법입니다. LinkedList.Contains 및 Remove를 비롯한 일반적인 LinkedList 클래스의 검색 방법입니다.
+0

입력 된 같음을 다음과 같이 단순화하십시오 :'return Id == other.Id' 그리고 객체는'return vessel! = null && Equals (vessels) '로 돌아갑니다. 적은 코드와 논리를 복제하지 않습니다. – RobH

+1

여기에서 'Any'를 사용하는 것은 "* 좋은 해결책이 아닙니다"또는 "* 우수 사례가 아닙니다 *"는 무의미합니다. 'Equals'를 구현하기위한 * 인수는 분명 유효하지만 성능/목록 크기가 요인 인 경우 OP 만 언급하지 않았습니다. – James

+0

내 업데이트보기 이것이 의미가 있기를 바랍니다. –

관련 문제