Reputation: 1561
I have a simple class that contains 4 double properties like this
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;}
}
Is there a simple way to check if all the properties have the same value? I'd rather not use if (Top == Bottom) && (Top == Left) ...
as it's somewhat messy IMHO. Can it be done in LINQ?
Upvotes: 1
Views: 182
Reputation: 37000
To underline what @CodeCaster already mentioned concerning the messyness the following would be the appropriate code for that:
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))
{
/* ... */
}
This checks for all properties within your type MyClass
by reflection. However everything is better than this approach, only added it for completeness. If you want it some stable you´d at least have to also prove if the class actually has any properties.
This only applies for non-indexed properties. If your property is indexed you´ll also have to prove for every element also which gets much dirtier.
Now compare this to the really nice and short Top == Bottom && Left == Top && Right == Left
from @Yuval.
Upvotes: 3
Reputation: 819
bool b = (Top == (new double[] { Top, Bottom, Left, Right }).Average());
This could be an alternative workaround?
Dom
Upvotes: -1
Reputation: 9467
Im really a big fan of writing a Method for cases like this, since it is reusable and has a name that tells whats happening here.
public static bool AllEqual<T>(T frist, params T[] values)
{
return values.All(v => Equal(first,v));
}
And then use it like this:
ObjectHelper.AllEqual(Top, Bottom, Left, Right);
Upvotes: 2
Reputation: 151586
LINQ works on collections. You don't have a collection, you have four separate properties.
Anything you're going to do to force this into LINQ is only going to make it more messy.
Just use plain old C#:
public bool AllPositionsEqual
{
get
{
return Top == Bottom
&& Left == Right
&& Left == Top;
}
}
This is clear to you now, and clear to another reader when they read it, and clear to you when you read it in a few months.
If you're going to stuff the properties in a collection just to be able to call a LINQ method on it in order to determine they are all the same, you are breaking the "principle of least astonishment". The reader of that code will go "WTF".
If, instead, you want to be able to do this on an arbitrary class (which would also be a really confusing requirement), you can do it as such:
Distinct()
. Then you'll have a legitimate use case for LINQ. Right now, you haven't.
Upvotes: 5
Reputation: 149538
You can insert them into a HashSet<double>
:
var doubles = new HashSet<double> { Top, Left, Right, Bottom };
if (doubles.Count == 1)
{
// Do stuff
}
Or use Enumerable.Distinct
:
var doubles = new[] { Top, Bottom, Left, Right };
if (doubles.Distinct().Count() == 1)
{
// Do stuff
}
But perhaps the most simple approach is to create a method (or a property, if you fancy that):
public class MyClass
{
public bool AreAllPropertiesSame()
{
return Top == Bottom && Left == Top && Right == Left;
}
}
Note any use of LINQ will incur more overhead then doing a simply if
check on 4 properties. I would definitely go with a simple property or method approach which is clear and concise. Don't defer to LINQ because you can, use it because it is the best tool for the job, where clearly here it isn't.
Upvotes: 5