EntitySet - 是否有一个理所当然的IList.Add没有设置分配?

Mar*_*ell 40 .net c# linq entityset linq-to-sql

向大多数列表添加项目有3种方法...

  • 通常通过直接的公共API方法 Add(SomeType)
  • 通过通用IList<T>.Add(T)接口
  • 通过非通用IList.Add(object)接口方法

你通常期望他们的行为或多或少相同.然而,LINQ EntitySet<T>是......在3.5和4.0上都很奇怪; 该IListAPI 不会标志设定为"分配" -其他两种机制 -这听起来微不足道,但它是因为它极大地影响系列化重要(即导致其跳过)的样板代码.

例:

EntitySet<string> set1 = new EntitySet<string>();
set1.Add("abc");
Debug.Assert(set1.Count == 1); // pass
Debug.Assert(set1.HasLoadedOrAssignedValues, "direct"); // pass

EntitySet<string> set2 = new EntitySet<string>();
IList<string> typedList = set2;
typedList.Add("abc");
Debug.Assert(set2.Count == 1); // pass
Debug.Assert(set2.HasLoadedOrAssignedValues, "typed list"); // pass

EntitySet<string> set3 = new EntitySet<string>();
IList untypedList = set3;
untypedList.Add("abc");
Debug.Assert(set3.Count == 1); // pass
Debug.Assert(set3.HasLoadedOrAssignedValues, "untyped list"); // FAIL
Run Code Online (Sandbox Code Playgroud)

现在......这让我感到非常惊讶; 以至于我花了2个多小时跟踪代码以隔离发生的事情.所以...

这有什么明智的理由吗?或者这只是一个错误?

(FWIW,set.Assign(set)3.5中也有一个问题,但现在已经修复了4.0.)

Eth*_*iac 20

有趣的是,现在已经确定了几个版本(你说明在4.0中修复了3.5问题).这是2007年帖子.4.0中的其余IList方法与方法正确绑定IList<T>.我认为有两种可能的解释(错误/特征种类):

  1. 这是Microsoft尚未修复的实际错误.
  2. 这是一个功能,其他一些Microsoft代码正在利用杠杆来添加项目而不设置HasLoadedOrAssignedValues.

它可能都是 - 框架内的其他代码所依赖的错误.听起来有人对自己说:

没有人真的要将它转换为IList然后调用Add方法,对吗?


Ric*_*key 8

令人惊讶的是,差异似乎源于这样一个事实:IList.AddIList<T>.Add方法实际上有不同的语义:

  • IList.Add如果添加的实体已经存在,则该方法失败
  • LIst<T>.Add如果已经存在,则该方法移除然后重新添加实体

这种差异的明显原因是IList.Add接口方法被定义为返回添加的实体的索引,对于典型的实现,该索引IList.Add将始终是Count之前的集合的索引Add.

在任何情况下,因为这两个实现是故意不同的,所以作者似乎只是偶然地忽略this.OnModified()IList.Add版本中的调用.