Удалить элемент из коллекции интерфейсов - PullRequest
0 голосов
/ 01 мая 2019

Я хочу использовать этот интерфейс:

public interface IFoo
{
 int Id { get; set; }
 string Name { get; set; }
 ICollection<IBar> IBars{ get; set; } //association with another entity
}

Моя реализация выглядит следующим образом:

public class Foo : IFoo
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Bar> Bars{ get; set; }

//Interface implementation
 public ICollection<IBar> IBars
        {
            get
            {
                return Bars.Cast<IBar>().ToList();
                //or return new List<ICardInquiry>(CardsInquiries);
            }

            set
            {
                if (value is ICollection<IBar>)
                    Bars= ((ICollection<IBar>)value).Cast<Bar>().ToList();
                else
                    throw new NotImplementedException();
            }
        }
}

Эта реализация не позволяет мне удалить элемент из коллекции:

IFoo iFoo = MyIFooFactory.CreateIFoo();
IBar iBar = iFooIBars.First();
iFoo.IBars.Remove(iBar);

Это НЕ удалит элемент!Я понимаю почему.Причина в том, что мой метод получения коллекции интерфейсов снова выглядит следующим образом:

public ICollection<IBar> IBars
        {
            get
            {
                return Bars.Cast<IBar>().ToList();
                //or return new List<ICardInquiry>(CardsInquiries);
            }
          ...
         }

IBars возвращает новый список, поэтому элемент удаляется из возвращенного списка, а не из исходной коллекции (столбцы).

Как я могу выйти из этой ситуации?Я действительно не хочу, чтобы IFoo знал о Баре и манипулировал только IBar.

1 Ответ

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

Элементы в Bars не удаляются, поскольку вы возвращаете новый список в получателе IBars:

return Bars.Cast<IBar>().ToList(); // ToList creates a new list.

Вы не можете конвертировать *От 1008 * до ICollection<IBar> без создания чего-то нового, поскольку универсальный параметр в ICollection является инвариантным.

Единственное, что вы можете здесь сделать, - это добавить метод Remove в IFoo:

 void RemoveIBar(IBar ibar);

И реализовать это так в Foo:

public void RemoveIBar(IBar ibar) {
    if (ibar is Bar) {
        Bars.Remove((Bar)ibar);
    } else {
        throw new NotImplementedException();
    }
}

Также проверка в установщике IBars является избыточной.

Очевидно, что это не тип-безопасный.Более безопасным для этого типом было бы заставить IFoo принимать универсальный параметр TBar и иметь ICollection<TBar>.Foo может затем реализовать IFoo<Bar>:

public interface IFoo<TBar> where TBar: IBar
{
    int Id { get; set; }
    string Name { get; set; }
    ICollection<TBar> TBars{ get; set; } //association with another entity
}

public class Foo : IFoo<Bar>
{

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Bar> Bars{ get; set; }

}

Но я думаю, это считается как IFoo, зная о Bar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...