我在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循环来比较对象。我觉得我错过了一些明显的东西。我知道任何有重复代码的地方你可以更好地实现,只是我不知道如何。这里的任何建议都会很棒。 谢谢你的帮助。
答案 0 :(得分: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
}
我认为这有助于您入门。
答案 1 :(得分: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;
}
答案 2 :(得分: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() + "");
}
}
此策略使您能够独立于需要使用它们的代码添加,删除或修改规则及其执行的操作。
答案 3 :(得分: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());
}
这只是一个开始,不确定你是否喜欢这个前提并且想要与它一起运行。