2016-09-28 8 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))。このクラスは、compareorを引数として(例えばDictionary<,>,HashSet<>またはさまざまなLINQ拡張メソッド)使用するさまざまな場所で使用できます。または、比較するオブジェクトのメソッドEquals()を自分で呼び出してください。

比較者は決して例外をスローしてはならず、(入力パラメータと入力パラメータの子値として)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); 
} 
関連する問題