Reputation: 25258
Basically I am giving the user an option to filter a set of files based on thier size.
The user picks a comparison type (Greater Than, Less Than, Equal To) from a drop down list, and then enters a size, in bytes, to compare to. This is what I have so far:
switch (cmboCompareType.SelectedText)
{
case "Greater Than":
fileOK = fi[i].Length > int.Parse(txtByteValue.Text);
break;
case "Less Than":
fileOK = fi[i].Length < int.Parse(txtByteValue.Text);
break;
case "Equal To":
fileOK = fi[i].Length == int.Parse(txtByteValue.Text);
break;
}
Is there a more elegant way to do this sort of comparison without repeating so much code in C#?
Upvotes: 4
Views: 6190
Reputation: 1500215
Two options:
int requiredSign;
switch (cmboCompareType.SelectedText)
{
case "Greater Than": requiredSign = 1; break;
case "Less Than": requiredSign = -1; break;
case "Equal To": requiredSign = 0; break;
default: throw new ArgumentException();
}
fileOK = Math.Sign(fi[i].Length.Compare(txtByteValue.Text)) == requiredSign;
static readonly Func<int, int, bool> GreaterThan = (x, y) => x > y;
static readonly Func<int, int, bool> LessThan = (x, y) => x < y;
static readonly Func<int, int, bool> Equal = (x, y) => x == y;
...
Func<int, int, bool> comparison;
switch (cmboCompareType.SelectedText)
{
case "Greater Than": comparison = GreaterThan; break;
case "Less Than": comparison = LessThan; break;
case "Equal To": comparison = Equal; break;
default: throw new ArgumentException();
}
fileOK = comparison(fi[i].Length, int.Parse(txtByteValue.Text));
Upvotes: 20
Reputation: 19677
I'm not a fan of case statements, same thing though, just another way.
var fileOK = new Dictionary<string, Func<int, int, bool>>
(StringComparer.OrdinalIgnoreCase)
{
{ "Greater Than", (x, y) => x > y },
{ "Less Than", (x, y) => x < y },
{ "Equal To", (x, y) => x == y }
}[cmboCompareType.SelectedText](fi.Length, int.Parse(txtByteValue.Text));
Upvotes: 5
Reputation: 25258
My own idea, inspired by the solutions that used Math.Sign(). Since the drop down box has three values, which will have an index of 0,1,and 2, I could subtract 1 to get -1,0,1, then use that to compare with the sign, as such:
int sign = Math.Sign(fi[i].Length.CompareTo(int.Parse(txtByteValue.Text)));
fileOK = sign == (cmboCompareType.SelectedIndex - 1);
This would be dependent on the items in the listbox being put in this specific order:
Less Than
Equal To
Greater Than
And of course would only work if these are the only values that will ever be in the listbox. Probably not the best solution, but I got a kick out of the fact that I accomplished this in only two lines of code.
EDIT: Techincally I could simplify this down to a single line of code:
fileOk=(cmboCompareType.SelectedIndex-1) == Math.Sign(fi[i].Length.CompareTo(int.Parse(txtByteValue.Text)));
Upvotes: 0
Reputation: 13640
You could also add the values -1, 0, 1 to the value property of each combo box item and then the code would look like:
fileOK = fi[i].Length.CompareTo(int.Parse(txtByteValue.Text) == cmboCompareType.SelectedValue;
Upvotes: 1
Reputation: 13640
Create an extension method on int
public static int Compare(this int a, int b, string compareType)
{
switch (CompareType)
{
case "Greater Than":
return fi[i].Length > int.Parse(txtByteValue.Text);
break;
case "Less Than":
return fi[i].Length < int.Parse(txtByteValue.Text);
break;
case "Equal To":
return fi[i].Length == int.Parse(txtByteValue.Text);
break;
}
}
and then use it as:
fileOK = fi[i].Length.Compare(int.Parse(txtByteValue.Text), cmboCompareType.SelectedTex);
Upvotes: 1
Reputation: 564383
If you have a map, you can use something like:
private int CompareOp(string Text)
{
switch (cmboCompareType.SelectedText)
{
case "Greater Than":
return 1;
case "Less Than":
return -1;
case "Equal To":
return 0;
}
}
// In your method:
fileOK = (fi[i].Length.CompareTo(value) == CompareOp(cmboCompareType.SelectedText);
Upvotes: 1
Reputation: 361585
int actual = Math.Sign(fi[i].Length.CompareTo(int.Parse(txtByteValue.Text)));
int expected;
switch (cmboCompareType.SelectedText)
{
case "Greater Than": expected = +1; break;
case "Less Than": expected = -1; break;
case "Equal To": expected = 0; break;
}
fileOK = (actual == expected);
Upvotes: 1
Reputation: 32960
int value = int.Parse(txtByteValue.Text);
int len = fi[i].Length;
switch (cmboCompareType.SelectedText)
{
case "Greater Than": fileOK = len > value; break;
case "Less Than": fileOK = len < value; break;
case "Equal To": fileOK = len == value; break;
}
TADA! Less repetition. ;P
Upvotes: 10