2013-03-05 3 views
2

나는 이와 같은 객체를 가진 기존 애플리케이션을 가지고있다.여러 컬렉션을 나타내는 데이터 구조 란 무엇입니까?

class MyObject{ 
    public MyCollection TypeOnes; 
    public MyCollection TypeTwos; 
    public MyCollection TypeThrees; 

    public MyCollection All; 
} 

class MyCollection : Collection{ 
    public boolean IsLoaded; 
} 

그리고 이렇게로드됩니다. 당신은 분명 모든 유형이 All 컬렉션 한 번에로드하지 않는 동기화 될 유형을 모두 표현하기 위해 가정되는 All 모음을 볼 수 있듯이

//using bool array for flag simplicity in example 
public void Load(ref MyObject obj, bool[] flags){ 
    if(flags[0]){ 
     obj.TypeOnes = LoadOnes(); 
     obj.TypeOnes.IsLoaded = true; 
    }else{ 
     obj.TypeOnes = new MyCollection(); 
    } 

    if(flags[1]){ 
     obj.TypeTwos = LoadTwos(); 
     obj.TypeTwos.IsLoaded = true; 
    }else{ 
     obj.TypeTwos= new MyCollection(); 
    } 

    if(flags[2]){ 
     obj.TypeThrees = LoadThrees(); 
     obj.TypeThrees.IsLoaded = true; 
    } else { 
     obj.TypeThrees = new MyCollection(); 
    } 

    if(flags[3]){ 
     obj.All = obj.TypeOnes.Clone().AddRange(obj.TypeTwos.Clone()).AddRange(obj.TypeThrees.Clone()); 
     obj.All.IsLoaded = true; 
    } else { 
     obj.All = new MyCollection(); 
    } 
} 

.

모든 유형 컬렉션을로드하는 단일 플래그를 만드는 것이지만 All 컬렉션을 사용하여 모든 유형 컬렉션에 즉시 액세스하고 동기화 할 수 있습니다. 리팩토링의 양을 제한하기 위해해야 ​​할 일이 있습니다. 읽기/쓰기가 가능하여 TypeOnes 컬렉션을 변경하면 All 컬렉션에 반영되고 그 반대의 경우도 마찬가지입니다.

여기에 사용할 수있는 기존 데이터 형식이 있습니까?
내가 만들려는 데이터 구조의 종류가 아닌 경우?

답변

2

어때? Concat은 컬렉션을 병합하고 모든 컬렉션을 한꺼번에 반환합니다.

class MyObject 
{ 
    public MyCollection TypeOnes; 
    public MyCollection TypeTwos; 
    public MyCollection TypeThrees; 

    public IEnumerable<T> All 
    { 
     get { return TypeOnes.Concat(TypeTwos.Concat(TypeThrees));} 
     // You can use Union() to handle duplicates as well, but it's slower. 
    } 
} 
4

당신은 세 포함 된 컬렉션에있는 개체의 복제를 만들 수있는 특별한 이유가없는 한 (당신이 사전 일반적인 .NET을 사용하는 경우 또는 IEnumerable을), 왜 아닌 IEnumerable<T>All을 구현 같은 뭔가 :

// Option: Preserve duplicates between collections 
public IEnumerable<T> All() 
{ 
    // Ensure child collections are loaded 
    return TypeOnes.Concat(TypeTwos).Concat(TypeThrees); 
} 

// Option remove duplicates between collections 
public IEnumerable<T> All() 
{ 
    // Ensure child collections are loaded 
    return TypeOnes.Union(TypeTwos).Union(TypeThrees); 
} 

포함 된 컬렉션에 일을 추가하는 기존 코드 계약이 유지되고, 당신은 All 그 컬렉션에 부실 또는 동기화 결코 없다는 것을 보장하는 그런 식으로.

이전 코드 계약에서 All은 초기화 된 이후 (아이들에 대한 업데이트가 All에 반영되지 않았기 때문에) 포함 된 컬렉션과 동기화되지 않게되었습니다. 이는 받아 들일 수 있거나 그렇지 않을 수있는 행동의 변화입니다.

+0

중복을 제거해야하는 특별한 이유가없는 한, 'Concat'은 'Union'보다 속도와 메모리 사용면에서 오버 헤드를 줄입니다. – Servy

+0

@Servy : 좋은 지적입니다. 나는 지난 며칠 동안'HashSet '으로 광범위하게 작업 해 왔으며 내 머리 속에 춤추는 환상을 가지고 있습니다 :-) 업데이트 중입니다. –

+0

+1 'Concat' 대신 Union 사용시 좋은 점 : Union이 올바른 컬렉션을 생성하지 못하는 경우. –

2

가능한 접근 - "all"을 IEnumerable<Base_type_for_items_in_other_collections>으로 표시하고 다른 모음을 연결하여 필요에 따라 만듭니다. 나는. 당신이 컬렉션의 작은 목록이있는 경우 기본 Enumerable.Concat가 작동합니다 : 발신자가 적절한 한계에 도달 할 때 항목에 액세스 할 중지 할 수 있도록 항목을 반환하는 yield return을 고려할 수있는 항목이 많이있을 수 있습니다

public IEnumerabe<MyObject> All {get 
{ 
    return TypeOnes.Concat(TypeTwos.Concat(TypeThrees)); 
}} 
0

때문에/항목이 발견되었다.

public class MyObject 
{ 
    public MyCollection TypeOnes { get; set;} 
    public MyCollection TypeTwos { get; set;} 
    public MyCollection TypeThrees { get; set;} 

    public IEnumerable<string> All 
    { 
     get 
     { 
      foreach (var item in TypeOnes.Union(TypeTwos).Union(TypeThrees)) 
      { 
       yield return item; 
      } 
     } 
    } 
} 

public class MyCollection : Collection<string> 
{ 
    public bool IsLoaded { get; set; } 
} 
+1

연합을 반복 할 이유가 없습니다. 그냥 돌려 보내. 그것은 이미'IEnumerable '입니다. –

+0

수익률 반환은 어떻게됩니까? 아이템 별 아이템 반환 – sll

+1

직접 'yield return'을 할 필요는 없습니다. 'Return TypeOnes.Union (TypeTwos) .Union (TypeThrees)'를 수행하는 경우,'All '이 반복 될 때 .NET 프레임 워크에 의해 "yield"가 내부적으로 수행됩니다. –

0

당신이 정말로 필요로하는 것은 권리, 노동 조합의 모든 다른 컬렉션을 커버하는 ICollection 인터페이스 또는 IEnumerable을 인터페이스입니다? 모든 것을로드 한 후에는 모든 컬렉션에 항목을 추가하지 않을 것이라고 가정합니다.그런 경우에는, 시도 :

public IEnumerable<MyBaseType> All; 

설정하려면 모든 :

obj.All = System.Linq.Enumerable.Concat<MyBaseType>(
      obj.TypeOnes, obj.TypeTwos).Concat(obj.TypeThrees); 

것은 그것이 아무튼 경우에도 모든 다른 컬렉션의 변경 사항을 반영 할 수 있도록해야 모든 선언에 대한

항목을 직접 추가 할 수 없습니다.

관련 문제