2016-09-28 3 views
1
using System; 
using System.Collections.Generic; 

//This is my class for obtaining certain values, putting them in a List<T> 
//and then use the List to do certain operations 
public class SRvaluesChecker 
{ 
    double currentPriceValue; 
    int totalVal, bullVal , bearVal , lineVal; 

    //The List is of a custom object type 
    List<MyValues> SRvalues = new List<MyValues>(); 

    for(int a = 0; a <= 1000; a++) 
    { 
     //Values are assigned to currentValue, totalVal, 
     //bullVal , bearVal and lineVal 

    } 

    //Check if the List has a particular value 
    if(SRvalues.Exists(x => x.SRprice == currentPriceValue) == false) 
    { 
     //Do something 
    } 
} 

//Here is the object I created so that I can store information of different 
//data types in the list 
public class MyValues : IEquatable<MyValues> 
{ 
    public override string ToString() 
    { 
     return "SRprice: " + SRprice + " total count: " + totalCount + 
     " bullish count: " + bullishCount + " bearish count: " + bearishCount + 
     " line type: " + lineType; 
    } 

    public MyValues(double SRprice, int totalCount, int bullishCount , int bearishCount, int lineType) 
    { 
     this.SRprice = SRprice; 
     this.totalCount = totalCount; 
     this.bullishCount = bullishCount; 
     this.bearishCount = bearishCount; 
     this.lineType = lineType; 
    } 

    public double SRprice { get; set; } 
    public int totalCount { get; set; } 
    public int bullishCount { get; set; } 
    public int bearishCount { get; set; } 
    public int lineType { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) return false; 
     MyValues objAsPart = obj as MyValues; 
     if (objAsPart == null) return false; 
     else return Equals(objAsPart); 
    }  

    //This currently only checks for one parameter (SRprice) but 
    //I want to code for the others as well 
    public bool Equals(MyValues other) 
    { 
     if (other == null) return false; 
     return (this.SRprice.Equals(other.SRprice)); 
    } 

    //Will override GetHashCode() and == and != operators later.   
} 

을 가진 목록 에 메서드가 포함되어 사용하고 존재하기 위하여 IEquatable에서 재정의하는 방법을, 나는 5 개 매개 변수를 사용하여 사용자 정의 개체가 내가되고 싶어 는 위의 코드에서 볼 수 있듯이 서로 다른 유형의

if(SRvalues.Exists(x => x.SRprice == currentPriceValue))... 
if(SRvalues.Exists(x => x.totalCount == totalVal))... 
if(SRvalues.Exists(x => x.bullishCount == bullVal))... 
if(SRvalues.Exists(x => x.bearishCount == bearVal))... 
if(SRvalues.Exists(x => x.lineType == lineVal))... 

즉, 메인 클래스에서 그 중 하나를 확인 할 수 있지만, 나는 내가 확인 오전 무엇 매개 변수를 구별 할 수 있도록 Equals 메서드 코딩에 대해 이동하는 방법을하지 확신합니다. 어떤 도움을 주시면 감사하겠습니다.

답변

0

이 아닌IEquatable을 구현해야합니다.

대신 IEqualityComparer<MyValues>을 구현하는 새 클래스를 만들고이를 사용하십시오.

public class MyClass 
{ 
    public int First { get; set; } 
    public string Second { get; set; } 
    public decimal Third { get; set; } 
} 

는 사실로 인해, 우리가 고려되어야한다 필드들이 구성하는 대한 우리의 비교자를 확인하고 싶은 것을, 우리가 열거를 만듭니다 :

그래서 간단한 예제로 시작하자

public class MyClassEqualityComparer : IEqualityComparer<MyClass> 
{ 
    private MyClassComparisonFields _Comparisons; 

    public MyClassComparer(MyClassComparisonFields comparisons) 
    { 
     _Comparisons = comparisons; 
    } 

    public bool Equals(MyClass x, MyClass y) 
    { 
     if(ReferenceEquals(x, y)) 
      return true; 

     if(ReferenceEquals(x, null)) 
      return false; 

     if(ReferenceEquals(y, null)) 
      return false; 

     if(_Comparisons.HasFlag(MyClassComparisonFields.First)) 
     { 
      if(!EqualityComparer<int>.Default.Equals(x.First, y.First)) 
       return false; 
     } 

     if(_Comparisons.HasFlag(MyClassComparisonFields.Second)) 
     { 
      if(!EqualityComparer<string>.Default.Equals(x.Second, y.Second)) 
       return false; 
     } 

     if(_Comparisons.HasFlag(MyClassComparisonFields.Third)) 
     { 
      if(!EqualityComparer<decimal>.Default.Equals(x.Third, y.Third)) 
       return false; 
     } 

     return true; 
    } 

    public int GetHashCode(MyClass x) 
    { 
     if(ReferenceEquals(x, null)) 
      return 0; 

     int hash = 97463; 

     if(_Comparisons.HasFlag(MyClassComparisonFields.First)) 
     { 
      hash = hash * 99713 + x.First.GetHashCode(); 
     } 

     if(_Comparisons.HasFlag(MyClassComparisonFields.Second) 
      && x.Second != null) 
     { 
      hash = hash * 99713 + x.Second.GetHashCode(); 
     } 

     if(_Comparisons.HasFlag(MyClassComparisonFields.Third)) 
     { 
      hash = hash * 99713 + x.Third.GetHashCode(); 
     } 

     return hash; 
    } 
} 
:

[Flags] 
public enum MyClassComparisonFields 
{ 
    None = 0, 
    First = 1, 
    Second = 2, 
    Third = 4, 
    All = 7, 
} 

이제 중요한 코드는 같음 비교 자체를 제공 : 가능한 모든 속성에 대한 비트 필드

비교자를 인스턴스화하고 원하는 필드를 지정할 수 있습니다 (예 : new MyClassEqualityComparer(MyClassComparisonFields.First | MyClassComparisonFields.Second)). 이 클래스는 비교자를 인수로 취하는 다양한 위치 (예 : Dictionary<,>, HashSet<> 또는 다양한 LINQ 확장 메소드)에서 사용할 수 있거나 비교하려는 객체에 대해 Equals() 메소드를 호출 할 수 있습니다.

비교 자는 절대로 예외를 throw해서는 안되며 입력 된 매개 변수와 입력 매개 변수의 자식 값으로 null 값을 처리해야합니다. 코드에서

원하는 속성 내 원하는 값 (들) (들)가 인스턴스을 코딩하고 목록에 대해 원하는 비교 자와 비교 :

var desiredMatch = GetDesiredSampleObject(); 
var comparer = new MyClassEqualityComparer(MyClassComparisonFields.First | MyClassComparisonFields.Third); 
var listOfCandidates = GetAvailableCandidates(); 
var matches = listOfCandidates.Where(candidate => comparer.Equals(desiredMatch, candidate)); 

foreach(var match in matches) 
{ 
    Console.WriteLine(match); 
} 
관련 문제