Ссылка на производный тип внутри себя - PullRequest
0 голосов
/ 30 апреля 2011

У меня есть что-то по ссылке:

public abstract class Wrapper<T, TWrapped>: where TWrapped : Wrapper<T, TWrapped>
{
   protected T baseObject;
   protected ICollection<T> baseList;
   protected ICollection<TWrapped> wrappedList;  
   public Wrapper (T base, ICollection<T> baseList, ICollection<TWrapped> wrappedList) { }
}

Тогда, когда я получаю от этого, мне нужно что-то вроде:

public class Base { }
public class Sample: Wrapper<Base, Sample> { }

Есть ли способ удалить TWrapped и создать ссылку на производный тип? Я пытался использовать ICollection<Wrapped<T>>, но потом я помню, что в ICollection.

нет ковариации.

РЕДАКТИРОВАТЬ: Пояснения, что я хочу с этой оберткой, это обеспечить функциональность удаления (и некоторые другие вещи) внутри объекта (я не могу изменить базовый объект, поэтому мне нужен обертка для придания этой функциональности и манипулирования ею). Этот абстрактный класс будет иметь такие методы:

void Remove()
{
   while(this.baseList.Remove(baseObject));
   this.baseList = null;
   while(this.wrappedList.Remove((TWrapped)this));
   this.wrappedList = null;
}

1 Ответ

0 голосов
/ 01 мая 2011

В итоге я меняю логику синхронизации списков и позволяю Элементам удалять себя.Я создал новый класс для хранения коллекции обернутых элементов:

public interface IWrapper<TModel>
{
    TModel Model { get; }
}

public class WrapperCollection<TWrapper, TModel> : ObservableCollection<TWrapper> where TWrapper : IWrapper<TModel>
{
    protected IList<TModel> modelList;

    public ReadOnlyObservableCollection<TWrapper> AsReadOnly { get; private set; }

    protected WrapperCollection(IList<TModel> modelList)
    {
        this.modelList = modelList;
        AsReadOnly = new ReadOnlyObservableCollection<TWrapper>(this);           
    }

    public WrapperCollection(IList<TModel> modelList, Func<TModel, TWrapper> newWrapper)
        :this(modelList)
    {
        foreach (TModel model in modelList)
            this.Items.Add(newWrapper(model));
    }

    public WrapperCollection(IList<TModel> modelList, Func<TModel, WrapperCollection<TWrapper, TModel>, TWrapper> newWrapper)
        : this(modelList)
    {
        foreach (TModel model in modelList)
            this.Items.Add(newWrapper(model, this));
    }

    protected override void ClearItems()
    {
        modelList.Clear();
        base.ClearItems();
    }

    protected override void InsertItem(int index, TWrapper item)
    {
        modelList.Insert(index, item.Model);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {
        modelList.RemoveAt(index);
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, TWrapper item)
    {
        modelList[index] = item.Model;
        base.SetItem(index, item);
    }
}

Используя образец класса:

public class wrappedInt: IWrapper<int>
{
    private WrapperCollection<wrappedInt, int> list;
    public Model { get; private set; }
    public wrappedInt(int source, WrapperCollection<wrappedInt, int> list)
    {
        this.Model = source;
        this.list = list;
    }
    public void RemoveMe()
    {
        if (list != null)
        {
            list.Remove(this);
            list = null;
        }
    }
}

Затем я могу создать экземпляр коллекции с помощью new WrapperCollection<wrappedInt, int>(listOfInts, (model, parent) => new wrappedInt(model, parent));.

...