我有两个具有不同值的相同类型的对象:
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.Prop1Min = 1
myItem1.Prop1Max = 4
myItem2.Prop1Min = 1
myItem2.Prop1Max = 5
这是真的,因为mtItem1 Prop1 min和max在myItem2 min和max。
的范围内条件应该是所有属性之间的AND,所以在我们检查所有25个属性之后,如果所有属性都在第二个对象的范围内,我们返回true。
使用Linq或其他算法除了传统的if-else外还有一种快速的方法吗?
答案 0 :(得分:3)
我会将属性重构为更多:
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;
否则你将不得不使用反射,这是快速的。
答案 1 :(得分:0)
Linq正在使用标准语句,如果...那么,对于每一个,没有魔法:)
如果最终目标只是比较,而不需要说明哪些属性不在范围内,那么你不需要全部检查它们,在第一个不平等的你可以结束检查。
因为你有这么多属性,所以你必须考虑将它保存在Dictionary或List中。或者使用动态属性(ITypedList),如果它将用于绑定。
答案 2 :(得分:0)
你真的应该做像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无法帮助您,因为您的数据不可枚举。
答案 3 :(得分:0)
为了完整起见,这是一个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; }
}
// ...
}