2011-02-28 2 views
2

문자열 필드의 방법으로 일반적인 종류의 ...여기 상황이 있는데 내가 진행하는 가장 좋은 방법이 무엇인지 확실하지 않다

내 프론트 엔드 코드 (ASP.NET)는 지속적으로 목록을 얻는다 UI 구성 요소 채우기를위한 비즈니스 객체. 최근에 모든 목록에 사용할 자연 정렬을 구현했습니다. (현재는 Lists of Strings를 정렬합니다.) 비즈니스 객체의 유형에 따라 다른 필드 이름을 정렬해야합니다. 필드에는 항상 문자열이 들어 있습니다. 나는 컴파일 타임에 필드 이름을 안다. Business Object에는 Object를 제외하고 공통 상위가 없습니다.

모든 유형의 Enumerable에 대해이 작업을 수행 할 수있는 한 가지 방법이 필요합니다. 기본 비즈니스 객체의 코드를 변경할 수 없습니다. 어떻게 이것에 대해 가겠습니까?

+0

LINQ를 사용하는 경우 IEnumerable을 구현하므로 OrderBy를 사용하여 목록을 정렬 할 수 있습니다. 예 : items.OrderBy (i => i.Name); – Zachary

답변

1

anonymous function을 사용하여 올바른 문자열을 검색 할 수 있습니다. 즉, 개체 목록과 람다 식 또는 익명 메서드 대리자를 모두 전달하여 정렬 메서드에 문자열을 추출해야합니다.

sort(listOfFoos, o => ((Foo) o).name()); 

저는 최근에 C#을 많이 사용하지 않았기 때문에 다른 사람들이 아마도 저를 울부 짖을 수 있습니다.

+0

여기에 몇 가지 좋은 제안이 있지만, 이것이 결국 내가 한 일이다. 감사. – Erix

0

각 비즈니스 개체에 대해 IComparable<T> 인터페이스를 구현하십시오.
그런 다음 정렬을 위해 자동으로 메서드를 사용할 LINQ OrderBy 메서드를 사용하십시오.

비즈니스 객체 클래스에 정렬 논리를 포함 할 수 없거나 포함하지 않으려면 IComparer<T>을 구현하고 OrderBy overload으로 전달할 수 있습니다.

+0

바로 그 이유는'IComparer ' – TDaver

+0

오. 발언 해줘서 고마워. –

5

같은 것 Linq's orderby?

당신은 IComparer에 자연 정렬을 구현해야 할 것,하지만 당신은 단지 사용하십시오 :

Items.OrderBy(i => i.SomeStringField, NaturalSorter); 
+0

문제는 정렬 할 모든 객체에 사용할 필드 'SomeStringField'가 없다는 것입니다. –

+0

항상 필드가 있다는 질문에 여러 컬렉션간에 항상 동일한 것은 아닙니다. OrderBy를 사용하면 각 콜렉션에 사용할 필드를 선택할 수 있습니다. SomeStringField는 필드를 선택할 수 있음을 보여주기 위해 사용되었습니다. – Massif

+0

이것은 유망 해 보입니다. 나는 그것에게 시험을 줄 것이다. – Erix

1

당신은 반사를 사용할 수 있습니다

private string GetStringValue(object input, string propertyName) 
{ 
    PropertyInfo pi = typeof(input).GetProperty(propertyName); 
    return pi.GetGetMethod().Invoke(input) as String; 
} 

이이 값을 얻을 것이다 객체에 대한 속성을 정의한 다음이를 기반으로 정렬을 적용 할 수 있습니다.

1

키 선택기를 만들어야합니다. Take a look at Enumerable.OrderBy. 두 번째 매개 변수는 키 선택기입니다. 당신이 강력한 형식의 방식으로 속성에 액세스 할 수있는 일반적인 유형을 가지고 있지 않기 때문에

delegate (object o) 
{ 
    if (o is BizType1) return ((BizType1)o).Property1; 
    else if (o is BizType2) return ((BizType2)o).Property2; 
} 
1

, 당신은 사용할 수 없습니다 계정에 비즈니스 오브젝트의 유형, 예를 적용하려면 구현 OrderBy 다른 답변에서 제안 된대로 직접.

당신은 순서의 각 항목에 값을 검색 할 property object에 대한 참조를 얻기 위해 반사를 사용하고 물어해야합니다 런타임에 당신이 필드를 알고 있다면 물론

public static IOrderedEnumerable<TSource> OrderByProperty<TSource>(
    this IEnumerable<TSource> source, 
    string propertyName) 
{ 
    var property = typeof(TSource).GetProperty(propertyName); 

    return source.OrderBy(item => (string) property.GetValue(item, null)); 
} 

, 정렬 할 정확한 유형의 목록 일 경우, OrderBy의 강력한 형식의 오버로드를 사용해야합니다. 이 추천은 목록에서 정렬 할 항목의 종류 (예 : IEnumerable<object>)를 모르는 경우에만 표시됩니다.

0
using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //lets say this is the list that you have you mah have more fields 
      List<Person> people = new List<Person>(); 

      people.Add(new Person(25, "Jhon")); 
      people.Add(new Person(22, "Antonio")); 
      people.Add(new Person(21, "Waid")); 
      people.Add(new Person(21, "Chris")); 
      people.Add(new Person(26, "Lacy")); 
      people.Add(new Person(21, "Albert")); 
      people.Add(new Person(45, "Tom")); 
      people.Add(new Person(65, "Bob")); 



      var query = from a in people // crate a query from your list in this case the list is people 
         where a.age > 18 && a.age < 50 // select just people that has an age greater than 0 and less than 100 
                 // maybe you want to filter some results if you dont then delete this line. 
         orderby a.name     // order the results by their name 
         select a.name;     // then select just the name. if you type select just a then query will 
                 // contain a list of ages too. 

      // loop though the results to see if they were ordered 
      foreach (string name in query) 
      { 
       Console.WriteLine(name); 
      }    
      Console.Read(); 

     } 
    } 

    // I created this class because I dont know what your list contains I know it has a string therefore I added a string 
    // you may add more properties and it will still work... 
    class Person 
    { 
     public int age; 
     public string name; 

     public Person(int a, string n) 
     { 
      age = a; 
      name = n; 
     } 
    } 
} 
+0

좋지만 다른 유형의 정렬 속성이 다를 때 유형을 수정할 수없는 경우 도움이되지 않습니다. –

관련 문제