2

あるオブジェクトを別のオブジェクトと比較する C# のクラスの関数があります。多かれ少なかれ Equals 関数ですが、コードが追加されています。私のオブジェクトにはかなりの数の変数があり、それぞれを比較して、異なるものがあればデータ テーブルに追加したいと考えています。今、私の関数は次のようになります。

    public bool compareSysInfo(SystemInfo expected, SystemInfo comp)
    {
        ComparePopup popup = new ComparePopup();
        bool finalResult = true;//initial assumption that they are equal
        //compares branding
        if (expected.branding != comp.branding)
        {
            finalResult = false;
            popup.addDataToTable("Branding", comp.getBranding() + "", expected.getBranding() + "");
        }
        //compares pro #
        if (expected.getPro() != comp.getPro())
        {
            finalResult = false;
            popup.addDataToTable("Pro Number", comp.getPro() + "", expected.getPro() + "");
        }

それはすべての変数についてそのように続きます。過度なif文は避けたいのですが、抽象メソッドを作ってループさせる方法はありますか? デリゲートを調べましたが、このコンテキストでそれらを使用する方法がわかりません。多分私はこれについて間違っているので、それらをコレクションに追加し、for ループを使用してオブジェクトを比較するなど、まったく異なることを行う必要があります。明らかな何かが欠けているように感じます。このような反復的なコードがあれば、より適切に実装できる場所を知っていますが、方法がわからないだけです。ここでのアドバイスは素晴らしいでしょう。助けてくれてありがとう。

4

4 に答える 4

1

戦略クラスを作成し、ルールごとに継承し、クラスに次のリストを提供します。

public MyClass {
 readonly IEnumerable<Rule> _rules;
 public MyClass(IEnumerable<Rule> rules) {
    _rules
 }

 public bool CompareSysInfo(SystemInfo expected, SystemInfo comp) {
   // i prefer linq over loops
   var result = from r in _rules
                where !r.CheckRule(expected, comp)
                select false;
   return result.Count() > 0; // only returns true if no rule checks return false
 }
}

次に、ルール チェックごとに、Rule クラス (またはインターフェイス) のインスタンスを実装します。

public abstract class Rule {
   protected ComparePopup Popup { get; private set; }
   protected Rule(ComparePopup popup) {
     Popup = popup;
   }
   public abstract bool CheckRule(SystemInfo expected, SystemInfo comp);
}

public class BrandingRule : Rule {

   public BrandingRule(ComparePopup popup) : base(popup) { }

   public override bool CheckRule(SystemInfo expected, SystemInfo comp) {
     var result = expected.branding == comp.branding;
     if(!result)
       Popup.addDataToTable("Branding", comp.getBranding() + "", expected.getBranding() + "");
   }
}

この戦略により、ルールを追加、削除、または変更し、ルールを使用する必要があるコードとは関係なくルールが行うことを行うことができます。

于 2012-04-26T19:50:00.960 に答える
1

クラスからすべてのプロパティを取得し、それらをループして値を取得し、比較することができます

Type type = expected.GetType();
PropertyInfo[] info = type.GetProperties();
foreach(PropertyInfo inf in info)
{
   if (info == null)
      return null; // or you can move on, based on what you need
   obj = info.GetValue(obj, null);
   //obj has the value, then you can compare them
 }

これはあなたが始めるのに役立つと思います。

于 2012-04-26T19:36:18.077 に答える
1

すべてのフィールドとプロパティを比較するには

public static bool MyCompare<T>(T obj1, T obj2)
{
    bool bp = obj1.GetType()
        .GetProperties()
        .All(p=>p.GetValue(obj1).Equals(obj2.GetType().GetProperty(p.Name).GetValue(obj2)));

    bool bf = obj1.GetType()
        .GetFields()
        .All(f => f.GetValue(obj1).Equals(obj2.GetType().GetField(f.Name).GetValue(obj2)));

    return bp && bf;
}
于 2012-04-26T19:44:21.913 に答える
0
private bool compareValue<T1, T2>(T1 first, T2 second, Func<T1, T2> selector)
{
  if(selector(first) != selector(second))
    ;//do stuff
}

次に、次のようなことができます。

public bool compareSysInfo(SystemInfo expected, SystemInfo comp)
{
  return compareValue(expected, comp, info => info.branding) &&
  compareValue(expected, comp, info => info.getPro());
}

それはほんの始まりにすぎません。前提が気に入って、それを実行したいかどうかはわかりません。

于 2012-04-26T19:35:26.973 に答える