2016-09-28 1 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.   
} 

Comme vous pouvez le voir dans le code ci-dessus, j'ai un objet personnalisé avec 5 paramètres et je veux être en mesure de vérifier l'un d'eux dans la classe principale à savoirComment passer outre à IEquatable de manière à utiliser Contenir et Exists méthodes dans une liste <T> avec différents types

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))... 

mais je ne suis pas sûr de savoir comment s'y prendre pour la méthode de codage Equals afin de distinguer ce paramètre, il est que je vérifie pour. Toute aide serait très appréciée.

Répondre

0

Vous devez pas mettre en œuvre IEquatable. Au lieu de créer une nouvelle classe qui implémente IEqualityComparer<MyValues> et l'utiliser.

Alors commençons par un exemple simple:

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

En raison du fait que nous aimerions faire de notre comparateur configurable sur lequel les champs doivent être pris en compte, nous allons créer un ENUM avec bitfields pour tous les biens disponibles:

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

vient maintenant le code important du comparateur d'égalité elle-même:

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; 
    } 
} 

Vous pouvez instancier un comparateur et lui donner les champs désirés (p.ex. new MyClassEqualityComparer(MyClassComparisonFields.First | MyClassComparisonFields.Second)). Cette classe peut ensuite être utilisée dans divers endroits qui prennent un comparateur comme argument (comme Dictionary<,>, HashSet<> ou différentes méthodes d'extension LINQ) ou appelez la méthode méthode Equals() sur vous-même pour tous les objets que vous souhaitez comparer. Sachez qu'un comparateur ne doit jamais lever une exception et doit gérer les valeurs nulles (en tant que paramètre d'entrée et valeur enfant du paramètre d'entrée).

Dans votre code vous codez prendre une instance qui a la valeur souhaitée (s) dans la propriété souhaitée (s) de et de le comparer avec le comparateur désiré contre votre liste:

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); 
}