문제

나는 추상적 인 기본 클래스에서 파생되는 일반 컬렉션 클래스의 계층 구조를 사용하여 추상 기본 클래스에서 파생되는 엔티티 항목을 저장합니다.

abstract class ItemBase { }

class MyItem : ItemBase
{
    public MyItem()
    {
    }
}


abstract class CollectionBase<T> : Collection<T> where T : ItemBase, new() { }

class MyCollection : CollectionBase<MyItem> { }

이 모델의 목표는 CollectionBase에서 파생 된 모든 클래스의 구성원에 대한 엄격한 유형의 징계를 시행하는 것입니다.u003CT> 이 회원들에게는 기본 공개 생성자가 있음을 보장합니다. 지금까지 그것은 작동합니다.

이제 CollectionBase에서 파생 된 클래스 인스턴스를 반환하는 공장 메소드를 만들고 싶습니다.u003CT> . 일반적인 접근 방식은 다음과 같습니다.

public CollectionBase<T> CreateCollection<T>();

... 또는 어쩌면 ...

public T Create CreateCollection<T>();

그러나 문제는 호출 루틴이 "T"가 필요한 것을 알지 못한다는 것입니다. 반품 할 특정 유형의 컬렉션을 결정 해야하는 것은 공장 방법 자체입니다. 따라서 "리턴 유형은 CollectionBase에서 파생된다고 말하는 비 게 릭 메소드 서명이 필요합니다.u003CT> ". 나는 이와 같은 것을 상상합니다 (합법적 인 경우) ...

public CollectionBase<> CreateCollection();

나는 이것이 가시적 인 일반적인 분산 문제 중 하나라고 생각하지만, 주제에 대한 에릭 립퍼트의 광범위한 설명을 읽은 후에도 C# 4.0에서 내가하려고하는 것이 실현 가능하고 단순한 것이 있는지 여부는 여전히 불분명합니다. C# 3.0의 해결 방법.

당신의 아이디어에 미리 감사드립니다.

도움이 되었습니까?

해결책

공장 방법이 단일 항목을 생성한다고 가정 해 봅시다. 너도 아마:

public ItemBase CreateItem();

당신은 사용해야합니다 ItemBase 더 구체적인 것을 알 수 없기 때문입니다. 해당 원리를 수집 방법에 적용하면 다음을 얻을 수 있습니다.

public CollectionBase<ItemBase> CreateCollection();

분산 부족으로 인해 발생하는 어댑터 클래스가 필요합니다. CollectionBase<ItemBase> 생성 된 실제 컬렉션을 랩핑합니다.

C# 4.0에서는 실제 컬렉션을 반환합니다.

편집하다: 공장은 어댑터가 포함 된 상태에서 다음과 같이 보일 수 있습니다.

public class CollectionFactory
{
    public CollectionBase<ItemBase> CreateCollection()
    {
        if(someCondition)
        {
            return CreateAdapter(new MyCollection());
        }
        else
        {
            return CreateAdapter(new MyOtherCollection());
        }
    }

    private static CollectionAdapter<T> CreateAdapter<T>(CollectionBase<T> collection) where T : ItemBase, new()
    {
        return new CollectionAdapter<T>(collection);
    }

    private class CollectionAdapter<T> : CollectionBase<ItemBase> where T : ItemBase, new()
    {
        private CollectionBase<T> _collection;

        internal CollectionAdapter(CollectionBase<T> collection)
        {
            _collection = collection;
        }

        // Implement CollectionBase API by passing through to _collection
    }
}

다른 팁

아마도 당신이 필요로하는 것은 다음과 같습니다.

public CollectionBase<Object> CreateCollection();

모든 클래스가 직간접 적으로 객체 클래스에서 상속되기 때문입니다.

나는 실제로 이것을하지 않았고 그것이 완전히 순진하지만 ...

public CollectionBase<Object> CreateCollection();

?

당신이 정말로 그것이 무엇이든 원한다면, 당신은 단지 iCollection을 반환 할 수 있고, 당신의 소비자는 .Cast<ItemBase>() 필요에 따라 확장 방법.

내가 이해 한 바에 따르면 .NET 4.0에서는 반환 할 수 있습니다. CollectionBase<ItemBase>, 그러나 나는 아직 베타에서 시도하지 않았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top