2009-09-25 4 views
4

기본적으로 사용자에게 크기에 따라 파일 집합을 필터링 할 수있는 옵션을 제공하고 있습니다.보다 작음, 크거나 같음 또는 같음 비교를 동적으로 전환하는 방법은 무엇입니까?

사용자가 비교 유형 (보다 큼,보다 작음, 같음)을 드롭 다운 목록에서 선택하고 비교할 크기 (바이트)를 입력합니다. C#에서 너무 많은 코드를 반복하지 않고 비교 이런 종류의 작업을 수행하는 더 우아한 방법은

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; 
} 

있습니까 : 이것은 내가 지금까지 가지고 무엇인가?

답변

10
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; 
} 

타다! 반복 횟수가 적습니다. ; P

+0

그 부분은 분명했습니다. 나는 "역동적 인"비교를 더 많이 찾고있었습니다. –

+0

글쎄, 당신은 동적 비교를 요구하지 않았다 ... 당신은 방금 적은 반복을 요구했다.나는 요점을 만들려고 노력했다. ; P – jrista

+0

글쎄, 타이틀은 "어떻게 동적으로 전환 할 것인가?"라고 말합니다. 제가 인정해야 할 것이지만, 이것은 가장 단순하고 아마 지금까지 모든 대답 중에서 가장 "우아합니다". –

18

두 가지 옵션 :

1) 사용은 compareTo 및 로그인 :

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; 

2) 대리자 사용 : 맵이있는 경우를

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)); 
+0

위임 옵션의 경우 +1입니다. 가독성을 희생하지 않고 DRY 문제를 원래 코드로 치료합니다. – JohnFx

+0

+1 : 특정 값보다는 대리자를 동적으로 선택하는 것이 과소 평가 된 디자인 패턴입니다. 또한 Math.Sign 접근법보다 확장 가능합니다. OP가 드롭 다운에 항목을 더 추가하면 Dictionary >에서 적절한 비교자를 쉽게 찾을 수 있도록 코드를 매우 쉽게 수정할 수 있습니다. – Juliet

+0

나는 옵션 2가 더 좋다. –

1
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); 
1

을 같은 것을 사용할 수 있습니다 :

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); 
1

은 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; 
    } 
} 

에 확장 메서드를 만든 다음으로 사용 : 당신은 각 콤보 상자 항목의 값 속성에 값 -1, 0, 1을 추가 할 수

fileOK = fi[i].Length.Compare(int.Parse(txtByteValue.Text), cmboCompareType.SelectedTex); 
+0

"Do not Repeat Yourself"문제를 해결하지 못함 –

+0

@ Nathan : 이것은 얼마나 자주 사용되는지에 따라 다릅니다. 확장 메서드가 모든 int에 표시되므로이 비교가 여러 다른 위치에서 수행되는 경우 Compare 메서드는 한 번만 구현되고 모든 곳에서 사용됩니다. –

1

코드는 다음과 같습니다.

fileOK = fi[i].Length.CompareTo(int.Parse(txtByteValue.Text) == cmboCompareType.SelectedValue; 
+0

그래, 내가 방금 추가 한 대답으로 나를 이끌 생각 프로세스입니다. 그러나 값을 추가하는 대신 인덱스를 하나씩 오프셋합니다. –

0

Math.Sign()을 사용하는 솔루션에서 영감을 얻은 저의 아이디어가 그 것입니다. 드롭 다운 상자에는 0,1 및 2의 인덱스가있는 3 개의 값이 있으므로 1을 빼면 -1,0,1을 얻은 다음이를 사용하여 부호와 비교할 수 있습니다.

int sign = Math.Sign(fi[i].Length.CompareTo(int.Parse(txtByteValue.Text))); 
fileOK = sign == (cmboCompareType.SelectedIndex - 1); 

이 목록 상자의 항목에 의존하는 것이 특정 순서에 넣어되고 :
미만
평등 큰


보다 그리고 물론
만 일하는 것이이 유일한 값이있는 경우 그것은 목록 상자에있게 될 것입니다. 아마 최선의 해결책은 아니 겠지만, 나는 두 줄의 코드만으로이 작업을 끝냈다.

편집 : Techincally 내가 코드 한 줄이 아래로 단순화 수 :

fileOk=(cmboCompareType.SelectedIndex-1) == Math.Sign(fi[i].Length.CompareTo(int.Parse(txtByteValue.Text))); 
5

그래도 난 경우 문 팬, 같은 일을, 또 다른 방법은 아니에요.


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)); 
+0

매우 흥미 롭습니다. –

관련 문제