2012-03-30 5 views
4

컬렉션에 사용자 지정 인덱서를 만들려고합니다. 여기 내 클래스는 다음과 같습니다컬렉션에 사용자 지정 인덱서 구현

비즈니스 클래스 :

public class UserCollection : Collection<User> 
{ 
    public new User this[int index] 
    { 
     get 
     { 
      return this.FirstOrDefault(x => x.UserID == index); 
     } 
    } 

} 

BL API 방법 :

public static Collection<User> GetUser() 
{ 
    return new UserCollection 
       { 
        new User {UserID = 2}, 
        new User {UserID = 4} 
       }; 
} 

사용법 :

Collection<User> users = GetUser(); 
    User user = users[2]; 

    } 

사용자 클래스는 사용자 ID와 같은 몇 가지 열이, 사용자 이름 등 콜렉션에서 인덱스를 통해 사용자를 가져오고 싶습니다. 여기서 인덱스는 사용자 ID입니다. 그러나 위의 사용법 코드는이를 수행하지 않고 부모 Collection 클래스의 인덱서를 고려하고 있습니다. 내 맞춤 인덱서를 사용하고 싶습니다. 나는 getUser 메소드의 반환 형식으로 UserCollection를 노출하여 작업을 수행 할 수 있습니다 후 솔루션이

UserCollection users = GetUser(); 

과 같은 코드를 사용하는 것입니다하지만 난 여기 BL 방법의 가장 일반적인 유형의 컬렉션은 반환 할 생각입니다 . 이 문제를 어떻게 해결할 수 있습니까?

+2

"GetByUserId"또는 그와 유사한 함수의 이름을 지정하면 호출자가 혼동을 덜 주며 인덱서 속성은 일반적으로 _nth_ 요소 (int 일 경우) 또는 해당 값이 키잉 된 요소 (예 : 문자열/기타 유형별). – Reddog

답변

0

인덱서는 가상 메서드가 아닙니다. 하위 클래스에 대한 인덱서를 정의 할 때 상위 구현을 숨기지 않고 상위 구현을 숨기므로 항목이 상위 유형으로 캐스트 될 때마다 인덱서의 상위 정의 (있는 경우)를 사용합니다. 개체가 자식 형식으로 캐스팅 된 경우 자식 개체의 인덱서 (이 경우 사용자 지정 개체)를 사용합니다.

Collection이 사용자 지정 컬렉션 인 경우 가상 클래스로 정의하고 new 대신 자식 클래스에 override을 사용하면 예상대로 작동합니다. 그렇지 않다면, 당신은 SOL입니다.

+0

여기에 컬렉션은 네임 스페이스 System.Collections.ObjectModel –

+0

아래에 있습니다 일반적으로 있습니다. 특정 상황에서 해당 클래스의 설명서에서는 보호 된 메서드를 재정의하여 기능을 재정의하는 방법을 구체적으로 설명합니다 (Justin의 다른 답변 참조). – Servy

0

대신 사전을 사용할 수 있습니까?

Dictionary<UserID,Users> 

그러면 ID로 키/값을 조회 할 수 있습니다.

4

Collection<T>에 대한 문서를 자세히 읽고 '상속인 참고 사항'섹션을주의 깊게 읽으십시오. 당신이하려는 일을하는 예를 보여주는 다른 페이지로 연결될 것입니다.

좀 더 편하게 만들 수있는 KeyedCollection<TKey, TItem> 클래스를 확인하시기 바랍니다. 맞춤 클래스는 다음과 같이 간단하게됩니다.

public class UserCollection: KeyedCollection<int, User> 
{ 

    public UserCollection() : base() {} 

    protected override int GetKeyForItem(User user) 
    { 
     return user.UserID; 
    } 
} 
0

컬렉션이 아닌 ICollection을 반환 할 수 있습니다. 그러면 인덱서를 가상으로 만들 수 있습니다.

public class UserCollection : ICollection<User> 
{ 
    public User this[int index] 
    { 
     get 
     { 
      return this.FirstOrDefault(x => x.UserID == index); 
     } 
    } 

    // all the other ICollection methods 

} 

public static ICollection<User> GetUser() 
{ 
    return new UserCollection 
       { 
        new User {UserID = 2}, 
        new User {UserID = 4} 
       }; 
} 

하지만 블라드에 동의합니다. 실제로 수집 물이 아닙니다. 나는 그것이 마치 사전과 같다고 생각한다. IDictionary를 고려하십시오. Enumerable Extension에서 ToDictionary()를 사용하여 키를 지정할 수도 있습니다.

2

UserCollectionCollection<User>까지 확장 하시겠습니까? UserCollection은 색인 생성 (컬렉션의 기본 항목 중 하나)이 다르므로 명확하게 Collection<User>이 아닙니다.

Collection<User>UserCollection의 필드로 포함시키고 인덱서에서 액세스하는 것이 좋습니다.

관련 문제