2012-05-22 2 views
1

다음 개체가 있고 사전이 인 경우 조건부로 중복이있는 경우을 지정합니다. 예를 들어, 하나의 사전에서 오직 두 개의 속성 만 내 키에 고유합니다. 두 번째 사전에서 모든 속성이 키에 대해 고유해야합니다.사전에 개체 추가 ... 부분적 고유성 테스트

질문 1 :

어떤 인터페이스 나는 이러한 목표를 달성하기 위해 오버라이드 (override) 할 필요가?

질문 2 (예를 들어 GetHashCode, IEqualityComparer는 운영자와 동일) :

내가 궁극적으로 키 값을 변경하는 속성을 변경하면 어떻게해야합니까? .NET 프레임 워크가 어떻게 든 나에게 이것을 처리했기 때문에 사전을 작성하면 더 적절할 것입니다. 그러나 그것에 대해서는 생각 해보지 않았습니다.

코드

public class EventData : IEqualityComparer<EventData> 
{ 
    public string ComputerName { get; set; } 
    public Guid? CategoryName { get; set; } 
    public string LogName { get; set; } 
    public int EventID { get; set; } 
    public long? EventUniqueTracker { get; set; } 

    public DateTime LastQueryDate { get; set; } 
    public DateTime? DateOfRecord { get; set; } 

    //public int QueryCount { get; set; } 
    public int QueryCount = 0 ;// 

    public string zData { get; set; } 

    public EventData(string computerName, Guid? categoryName, string logName, int eventID, long? eventUniqueTracker, int queryCount) 
    { 
     ComputerName = computerName; 
     CategoryName = categoryName; 
     LogName = logName; 
     EventID = eventID; 
     EventUniqueTracker = eventUniqueTracker; 

     LastQueryDate = DateTime.Now; 
     QueryCount = queryCount; 
    } 

    public EventData() 
    { 
    } 

    public override int GetHashCode() 
    { 
     return GetHashCode(HashType.ZCompCatLogEventAllData); 
    } 
    public object GetString(HashType hType) 
    { 
     switch (hType) 
     { 
      case HashType.AComputerName: 
       return ComputerName; 
       break; 
      case HashType.BCompAndCat: 
       return new { A = ComputerName, B = CategoryName }; 
       break; 
      case HashType.CCompCatLog: 
       return new { A = ComputerName, B = CategoryName, C = LogName }; 
       break; 
      case HashType.DCompCatLogEvent: 
       return new { A = ComputerName, B = CategoryName, C = LogName, D = EventID }; 
       break; 
      case HashType.ECompCatLogEventUserDefined1: 
      case HashType.FCompCatLogEventUserDefined2: 
      case HashType.ZCompCatLogEventAllData: 
       return new { A = ComputerName, B = CategoryName, C = LogName, D = EventID, E = EventUniqueTracker }; 
      default: 
       break; 
     } 
     return new object { }; 
    } 

    public int GetHashCode(HashType hType) 
    { 
     return GetString(hType).GetHashCode(); 
     return 1; 
    } 

    public override string ToString() 
    { 
     return ComputerName + " " + CategoryName + " " + LogName + " " + EventID + " " + EventUniqueTracker; 
    } 

    public bool Equals(EventData x, EventData y) 
    { 
     return x.ComputerName == y.ComputerName && 
       x.CategoryName == y.CategoryName && 
       x.LogName == y.LogName && 
       x.EventID == y.EventID && 
       x.EventUniqueTracker == y.EventUniqueTracker; 
    } 

    public int GetHashCode(EventData obj) 
    { 
     EventData ci = (EventData)obj; 
     // http://stackoverflow.com/a/263416/328397 
     return new { A = ci.ComputerName, B = ci.CategoryName, C = ci.LogName, D = ci.EventID, E = ci.EventUniqueTracker }.GetHashCode(); 
    } 
} 

답변

2

그것은 당신이 IEqualityComparer<EventData>를 구현해야합니다 같은 소리 -하지만 EventData 자체 내에서 하지. 두 개의 개별 구현을 작성하십시오. 하나는 첫 번째 동일성 개념이고 다른 하나는 두 번째 구현 개념입니다. 당신은 당신이 EventDataIEquatable<EventData>를 구현하고 두 번째 사전을 만들 때 비교자를 지정할 수없는 경우에 EventData의 "자연"평등으로 두 번째 경우를 처리 할

var first = new Dictionary<EventData, string>(new PartialDataEqualityComparer()); 
var second = new Dictionary<EventData, string>(new FullDataEqualityComparer()); 

아니면 : 그런 다음 당신의 사전을 만들 .

기본적으로,이 유형의 인스턴스의 두 인스턴스를 비교 할 수있다 "라고 당신이 IEqualityComparer<T>을 구현하는 반면,"이러한 유형의 인스턴스 T의 인스턴스에 대해 자체을 비교 할 수있다 "라고 IEquatable<T>를 구현 T ".

궁극적으로 키 값을 변경하는 속성을 변경하면 어떻게해야합니까?

기본적으로 채워집니다. 사전에서 해당 키를 다시 찾을 수 없습니다 (또는 적어도 아마도). 가능한 한 신중하게 이것을 피해야합니다. 개인적으로 나는 보통 사전 키에 대한 좋은 후보자 인 클래스가 이고 좋은 후보자임을 알게됩니다.

+0

이 대화에서'GetHashCode() '는 어떤 관계가 있습니까? 이러한 인터페이스 중 Dictionary 또는 ConcurrentDictionary와 관련이있는 인터페이스는 무엇입니까? – LamonteCristo

+0

흠 ... 나는 내가 변경할 수있는 형식 클래스를 만들어이 작업을 수행 할 수 있다고 생각하고 내 주 클래스를 상속받습니다. 나는 IEquatable의 어느 오버로드가 더 일반적인 클래스로 캐스팅 될 때 보이는지 궁금하다. – LamonteCristo

+0

@ makerofthings7 : IEqualityComparer와 IEquatable 둘 다 Dictionary와 ConcurrentDictionary와 관련있다. * GetHashCode 메서드에 대한 이야기는 분명하지 않습니다. 별도의 비교자를 지정하면 개체에 의해 선언 된 GetHashCode 메서드가 사용되지 않습니다. 나는 개인적으로 상속을 평등과 함께 사용하지 않으려 고 노력할 것입니다. 올바르게 구현하기가 어렵고 혼란 스럽습니다. –