2014-04-27 2 views
3

메서드 IEnumerator<T>을 재정의하는 데 도움이 필요합니다. 열거 중에 dictionary.Values와 같은 요소 만 반환하는 사전 클래스가 필요합니다. foreach에서는 foreach가 IEnumerator<T> 대신 IEnumerator을 사용하지만 LINQ 메서드는 내 클래스의 인스턴스에서 작동하지 않으므로 foreach에서는 작동합니다. 내가 linq 메서드를 호출하려고하면 소스 유형에 대한 쿼리 패턴 구현을 찾을 수 없습니다. '어디서'를 찾을 수 없습니다.C# 재정의 메서드

public abstract class SpecialDictionary : Dictionary<TKey, MyClass>, IEnumerable<MyClass> 
{ 
    public Add(MaClass item) 
    { 
     Add(item.Id, item); 
    } 

    new public IEnumerator<MyClass> GetEnumerator() 
    { 
     return this.Values.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

id로 요소에 빠르게 액세스 할 수있는 항목 모음이 필요합니다. 모든 요소에는 Guid ID가 있습니다. 이것은 나에게 좋은 생각 인 것 같았지만이 솔루션에 대한 귀하의 제안을 환영합니다.

+0

방금'this.Values'을 반환 할 수 없습니다 나는 당신의 반환 형식은'IEnumerable을해야한다 생각 ' –

+0

_ "하지만 LINQ 방법이 작동하지" _ - 항상 (일어나지 않는) 일이나 오류 메시지 등을 설명하십시오. 우리를 추측하지 마십시오. –

+0

GetEnumerator() 전에 'new'를 제거한 다음 추적 기록을 읽습니다. 이것이 흔적의 시작입니다. –

답변

3

이제 SpecialDictionaryIEnumerable<KeyValuePair<Guid,MyClass>>IEnumerable<MyClass>을 모두 구현해야하는 문제가 있습니다. 이러한 모호성 때문에 LINQ는이 두 가지 옵션 중 하나를 선택할 수 없으며 둘 중 하나를 선택하지 않습니다. 확장 방법은 여전히 ​​작동하지만, 명시 적 형식 매개 변수가 필요합니다

MyClass item = dict.First<MyClass>(); 

과 동등 :

KeyValuePair<Guid, MyClass> pair = dict.First<KeyValuePair<Guid, MyClass>>(); 

LINQ, 그러나, 당신은 명시 적 유형 매개 변수를 추가 할 수 없습니다 것, 그래서 작동하지 않습니다. 나의 충고 : 그렇게하지 마라. 사용자가 값을 처리하려고하는 경우 .Values을 통해 값을 변경하도록합니다. 여기


캡슐화의 예 :

public class SpecialDictionary : IEnumerable<MyClass> 
{ 
    private readonly Dictionary<Guid, MyClass> inner = new Dictionary<Guid, MyClass>(); 
    public void Add(MyClass item) 
    { 
     inner.Add(item.Id, item); 
    } 

    public MyClass this[Guid id] 
    { 
     get { return inner[id]; } 
     set { inner[id] = value; } 
    } 
    public bool TryGetValue(Guid id, out MyClass value) 
    { 
     return inner.TryGetValue(id, out value); 
    } 
    public IEnumerator<MyClass> GetEnumerator() 
    { 
     return inner.Values.GetEnumerator(); 
    } 
    public int Count { get { return inner.Count; } } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 
+0

감사합니다. 이 방법을 사용할 수있는 방법이 정말로 없습니까? 나는 항상 그것들을 사용하지는 않는다 .Value – Lenny

+1

@Lenny 다른 일은 그것을 상속하는 대신에 * 캡슐화하는 것이다. 그런 다음 형식은 하나의 'IEnumerable 'API 만 구현합니다. –

+0

@Lenny LINQ –