快速比较两个对象的属性



我有两个相同类型但值不同的对象:

    public class Itemi
    {
    public Itemi()
    {
    }
    public int Prop1Min { get; set; }
    public int Prop1Max { get; set; }
    public int Prop2Min { get; set; }
    public int Prop2Max { get; set; }
    public int Prop3Min { get; set; }
    public int Prop3Max { get; set; }
    ...................................
    public int Prop25Min { get; set; }
    public int Prop25Max { get; set; }
    }

现在我实例化两个这种类型的对象,并为它们的属性添加一些值。

Itemi myItem1 = new Itemi();
myItem1.Prop1Min = 1;
myItem1.Prop1Max = 4;
myItem1.Prop2Min = 2;
myItem1.Prop2Max = 4;
myItem1.Prop3Min = -1;
myItem1.Prop3Max = 5;
.............................
myItem1.Prop25Min = 1;
myItem1.Prop25Max = 5;
Itemi myItem2 = new Itemi();
myItem2.Prop1Min = 1;
myItem2.Prop1Max = 5;
myItem2.Prop2Min = -10;
myItem2.Prop2Max = 3;
myItem2.Prop3Min = 0;
myItem2.Prop3Max = 2;
................................
myItem2.Prop25Min = 3;
myItem2.Prop25Max = 6;

做这个比较的最好和最快的方法是什么:

  • 从myItem1中获取每个属性并检查prop1 - 25min和Max的值是否在myItem2 prop1 - 25min和Max的范围内

的例子:

   myItem1.Prop1Min = 1
   myItem1.Prop1Max = 4
   myItem2.Prop1Min = 1
   myItem2.Prop1Max = 5

这是True,因为mtItem1 Prop1 min和max在myItem2 min和max的范围内。

所有属性之间的条件应该是AND,所以最后我们检查了所有25个属性,如果它们都在第二个对象的范围内,我们返回true。

是否有一个快速的方法来做到这一点使用Linq或其他算法,除了传统的if-else?

我会将这些属性重构为:

public class Item
{
    public List<Range> Ranges { get; set; }
}
public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }
}

那么你的比较方法可以是:

if (myItem1.Ranges.Count != myItem2.Ranges.Count)
{
    return false;
}
for (int i = 0; i < myItem1.Ranges.Count; i++)
{
    if (myItem1.Ranges[i].Min < myItem2.Ranges[i].Min ||
        myItem1.Ranges[i].Max > myItem2.Ranges[i].Max)
    {
        return false;
    }
}        
return true;

Linq使用标准语句,如if…那么,对于彼此来说,就没有魔法了:)

如果最终目的只是比较,而不需要说明哪些属性不在范围内,则不需要全部检查,在第一个不相等处可以结束检查。

因为你有这么多属性,你必须考虑将它们保存在Dictionary或List中。或者使用动态属性(ITypedList),如果它将用于绑定。

你真的应该像Ginosaji建议的那样做。

但如果你想用你当前的数据模型,我将如何解决它。快乐的打字。:)

public static bool RangeIsContained(int outerMin, int outerMax, int innerMin, int innerMax)
{
    return (outerMin <= innerMin && outerMax >= innerMax);
}
public bool IsContained(Itemi outer, Itemi inner)
{
    return RangeIsContained(outer.Prop1Min, outer.Prop1Max, inner.Prop1Min, inner.Prop1Max)
        && RangeIsContained(outer.Prop2Min, outer.Prop2Max, inner.Prop2Min, inner.Prop2Max)
        // ...
        && RangeIsContained(outer.Prop25Min, outer.Prop25Max, inner.Prop25Min, inner.Prop25Max);
}

对于您的数据模型,这基本上是除了反射(慢!)之外的唯一方法。LINQ无法帮助您,因为您的数据是不可枚举的。

为了完整起见,这里是一个LINQ解决方案(但它的性能和可读性不如Ginosaji的解决方案!)

public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }
    public static bool IsContained(Range super, Range sub)
    {
        return super.Min <= sub.Min
            && super.Max >= sub.Max;
    }
}
public class Itemi
{
    public Itemi()
    {
        properties = new Range[25];
        for (int i = 0; i < properties.Length; i++)
        {
            properties[i] = new Range();
        }
    }
    private Range[] properties;
    public IEnumerable<Range> Properties { get { return properties; } }
    public static bool IsContained(Itemi super, Itemi sub)
    {
        return super.properties
            .Zip(sub.properties, (first, second) => Tuple.Create(first, second))
            .All((entry) => Range.IsContained(entry.Item1, entry.Item2));
    }
    public Range Prop1 
    { 
        get { return properties[0]; }
        set { properties[0] = value; }
    }
    public Range Prop2
    {
        get { return properties[1]; }
        set { properties[1] = value; }
    }
    // ...
}

相关内容

  • 没有找到相关文章

最新更新