我将map(),reduce()和where(qlint:string)添加到我的Spring4D分支中。 当我编写这些函数时,我发现列表的行为在以不同方式创建时存在差异。
如果我使用TList<TSomeClass>.create
创建它们,则枚举中的对象属于TSomeClass
类型。
如果我使用TCollections.CreateList<TSomeClass>
创建它们,则枚举中的对象属于TObject
类型。
所以问题是:
使用TList<TSomeClass>.create
是否存在缺点?
换句话说:我为什么要使用TCollections.CreateList<TSomeClass>
?
btw:使用TCollections.CreateList我有一个TObjectList而不是TList。所以它应该被称为TCollections.CreateObjectList ......但那是另一个故事。
答案 0 :(得分:11)
根据编译器版本的不同,许多Spring.Collections.TCollections.Create
方法正在应用编译器无法实现的功能:将实现折叠到非常简单的泛型类中。有些方法是从XE开始做的,有些只是因为XE7(GetTypeKind
内在函数可以在编译时进行类型解析 - 例如参见无参数TCollections.CreateList<T>
。
如果要创建许多不同类型的IList<T>
(其中T是类或接口),这会大大减少二进制大小,因为它会将它们折叠为TFolded(Object|Interface)List<T>
。但是,通过界面,您可以按照指定的方式访问项目,ElementType
属性也会返回正确的类型,而不仅仅是TObject
或IInterface
。在柏林,它为每个不同的对象列表添加不到1K,而如果由于所有内部类涉及可以在IList<T>
上调用的不同操作所涉及的所有内部类,它将增加大约80K。
至于TCollections.CreateList<T>
返回由IList<T>
支持的TFoldedObjectList<T>
,当T是完全按照设计的类时。由于OwnsObject
已作为False
传递,因此其行为与TList<T>
完全相同。
Spring4D集合是基于接口的,所以只要它的行为与接口的契约相对应,接口后面的类并不重要。
确保您只将IList<T>
而不是TList<T>
列在一起 - 您可以双向创建它们(使用TCollections
方法时我之前提到过的好处)。在我们自己的应用程序中,一些地方仍在使用类的构造函数,而许多其他地方正在使用Spring.Collections.TCollections
中的静态方法。
BTW:
我在你的fork和imo中看到了活动,没有必要实现Map / Reduce,因为那已经存在了。由于Spring4D集合是在.NET之后建模的,因此它们被称为Select
和Aggregate
(请参阅Spring.Collections.TEnumerable
)。它们直接在IEnumerable<T>
上不可用,因为接口不能有通用的参数化方法。