我想使用此接口:
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);
这不会删除元素!我确实了解原因。原因是我的界面集合getter,再次如下:
public ICollection<IBar> IBars
{
get
{
return Bars.Cast<IBar>().ToList();
//or return new List<ICardInquiry>(CardsInquiries);
}
...
}
ibars返回一个新列表,因此该元素已从返回的列表中删除,而不是从原始集合(bars(中删除。
我如何摆脱这种情况?我真的不想知道bar,而只想知道ibar。
Bars
中的项目未删除,因为您正在 IBars
的Getter中返回 new 列表:
return Bars.Cast<IBar>().ToList(); // ToList creates a new list.
您不能真正将ICollection<Bar>
转换为ICollection<IBar>
而不创建新内容,因为ICollection
中的通用参数是不变的。
您唯一可以做的就是在IFoo
中添加Remove
方法:
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
。