查找类中的所有属性是否相同
本文关键字:属性 是否 查找 | 更新日期: 2023-09-27 18:27:13
我有一个简单的类,它包含4个类似的双重属性
public MyClass
{
public MyClass(double all = 0)
{
Top = Bottom = Left = Right = all;
}
public MyClass(double lr = 0, double tb = 0)
{
Top = Bottom = tb;
Left = Right = lr;
}
public MyClass(double l = 0, double r = 0, double t = 0, double b = 0)
{
Top = t;Bottom = b;Left = l;Right = r;
}
public double Top {get; private set;}
public double Bottom {get; private set;}
public double Left {get; private set;}
public double Right {get; private set;}
}
有没有一种简单的方法可以检查所有属性是否具有相同的值?我宁愿不使用if (Top == Bottom) && (Top == Left) ...
,因为它有点乱IMHO。可以在LINQ中完成吗?
你要做的任何事情都会迫使它进入LINQ,只会让它变得更加混乱。
只需使用普通的旧C#:
public bool AllPositionsEqual
{
get
{
return Top == Bottom
&& Left == Right
&& Left == Top;
}
}
这一点现在你很清楚,当另一位读者读到它时,你也很清楚,几个月后你读到它。
如果您将属性填充到集合中,只是为了能够对其调用LINQ方法以确定它们都是相同的,那么就违反了"最小惊讶原则"。该代码的读取器将转到"WTF"。
相反,如果你想在任意类上做到这一点(这也是一个非常令人困惑的要求),你可以这样做:
- 使用反射获取所有属性
- 获取集合中此实例的所有属性值
- 在此集合上,调用
Distinct()
然后您将拥有一个合法的LINQ用例。现在,你还没有。
您可以将它们插入HashSet<double>
:
var doubles = new HashSet<double> { Top, Left, Right, Bottom };
if (doubles.Count == 1)
{
// Do stuff
}
或者使用Enumerable.Distinct
:
var doubles = new[] { Top, Bottom, Left, Right };
if (doubles.Distinct().Count() == 1)
{
// Do stuff
}
但也许最简单的方法是创建一个方法(或者一个属性,如果你喜欢的话):
public class MyClass
{
public bool AreAllPropertiesSame()
{
return Top == Bottom && Left == Top && Right == Left;
}
}
请注意,任何LINQ的使用都会比对4个属性进行简单的if
检查产生更多的开销。我肯定会选择一种简单明了的属性或方法。不要因为可以而听从LINQ,使用它是因为它是工作的最佳工具,而这里显然不是。
为了强调@CodeCaster已经提到的关于消息的内容,以下是合适的代码:
var properties = typeof(MyClass).GetProperties();
var first = proerties[0].GetValue(myInstance, null);
if (properties.Select(x => x.GetValue(myInstance, null)).All(x => x.Equals(first))
{
/* ... */
}
这将通过反射检查类型MyClass
中的所有属性。然而,一切都比这种方法好,只是为了完整性才添加它。如果你想让它稳定,你至少还必须证明这个类是否真的有任何属性。
这仅适用于未编制索引的属性。如果你的财产被索引了,你还必须证明每一个元素都会变得更脏。
现在将其与@Yuval的Top == Bottom && Left == Top && Right == Left
进行比较。
我非常喜欢为这样的情况编写一个方法,因为它是可重用的,并且有一个可以告诉这里发生了什么的名称。
public static bool AllEqual<T>(T frist, params T[] values)
{
return values.All(v => Equal(first,v));
}
然后像这样使用:
ObjectHelper.AllEqual(Top, Bottom, Left, Right);
bool b = (Top == (new double[] { Top, Bottom, Left, Right }).Average());
这可能是另一种变通方法?
Dom