作为一项智力练习,我想我可以看到在TypeScript (0.9.5)中实现一些TypeScript泛型成员是多么的接近,我已经了解到了List<T>,但不确定我能否取得进展。
(我意识到这是有解决办法的,但我正特别尝试使用与.Net库中相同的实现,主要是试图了解TypeScript中仍然存在的局限性。)
无论如何,忽略了我似乎无法以任何有意义的方式重载构造函数这一事实,在.Net源代码中,构造函数List(IEnumerable<T> collection)检查传递的枚举不为空,然后使用ICollection<T> c = collection as ICollection<T>将其转换为ICollection。
在TypeScript中,我执行这个var c: ICollection<T> = collection (集合是一个IEnumerable<T>),但是得到以下错误:
Cannot convert 'IEnumerable<T>' to 'ICollection<T>': Type 'IEnumerable<T>' is missing property 'Add' from type 'ICollection<T>'。
我的当前代码如下:
export module System {
export module Collections {
export interface IEnumerator {
MoveNext(): boolean;
Reset(): void;
Current(): any;
}
export interface IEnumerable {
GetEnumerator(): IEnumerator;
}
export interface ICollection extends IEnumerable {
CopyTo(array: any[], index: number): void;
Count(): number;
SyncRoot(): any;
IsSynchronized(): boolean;
}
export interface IList extends ICollection {
[index: number]: any;
Add(value: any): number;
Contains(value: any): boolean;
Clear(): void;
IsReadOnly: boolean;
IsFixedSize: boolean;
IndexOf(value: any): number;
Insert(index: number, value: any): void;
Remove(value: any): void;
RemoveAt(index: number): void;
}
export module Generic {
export interface IEnumerator<T> extends System.Collections.IEnumerator {
Current(): T;
}
export interface IEnumerable<T> extends System.Collections.IEnumerable {
GetEnumerator(): IEnumerator<T>;
}
export interface ICollection<T> extends IEnumerable<T> {
Add(item: T): void;
Clear(): void;
Contains(item: T): boolean;
CopyTo(array: T[], arrayIndex: number): void;
Remove(item: T): boolean;
Count(): number;
IsReadOnly(); boolean;
}
export interface IList<T> extends ICollection<T> {
IndexOf(item: T): number;
Insert(index: number, item: T): void;
RemoveAt(index: number): void;
[index: number]: T;
}
export interface IReadOnlyCollection<T> extends IEnumerable<T> {
Count(): number;
}
export interface IReadOnlyList<T> extends IReadOnlyCollection<T> {
[index: number]: T;
}
export class List<T> implements IList<T>, System.Collections.IList, IReadOnlyList<T> {
private _defaultCapacity: number = 4;
private _items: T[];
private _size: number;
private _version: number;
private _syncRoot: any;
constructor(collection?: IEnumerable<T>, capacity?: number) {
// NOTE: Capacity will be ignored is Collection is not null
// This is because we don't appear to be able to overload ctors in TypeScript yet!
if (collection == null) {
if (capacity == null) {
this._items = new Array<T>(0);
}
else {
this._items = new Array<T>(capacity);
}
} else {
var c: ICollection<T> = collection;
}
}
}
}
}
}有没有其他人尝试过与接口进行协/反向转换?如果是的话,你们相处得怎么样?
谢谢,
发布于 2014-01-27 15:07:03
虽然TypeScript不直接支持协/反向方差,但您可以只在这个实例中使用类型断言(在其他语言(如C#)中,这种断言看起来就像强制转换):
var c: ICollection<T> = <ICollection<T>>collection;TypeScript没有一种简单的方法来确认类型断言操作是正确的(就像collection对象实际上是一个ICollection<T>),所以您需要决定这对您是否重要。
而且,如果希望another想法稍微简化代码,可以为capacity参数使用默认值:
constructor(collection?: IEnumerable<T>, capacity: Number = 0) {
if (!collection) {
this._items = new Array<T>(capacity);
} else {
var c: ICollection<T> = <ICollection<T>> collection;
}
}TypeScript编译器将为如下所示的值生成一个检查:
if (typeof capacity === "undefined") { capacity = 0; }发布于 2014-01-27 15:08:48
您可以使用TypeScript中的类型断言来抑制警告:
var c: ICollection<T> = <ICollection<T>> collection;类型断言实际上不强制转换值--在运行时,这些类型注释或断言都不存在,因为它们都被删除了。运行时值完全不受类型断言的影响。
但这并不能解决没有add方法的问题。
此外,在这里,null对于您的测试来说是一个不太可能的值:
if (collection == null) {null通常只用于故意缺失值,例如,您更有可能遇到undefined。您可以使用短手测试这两种方法:
if (!collection) {我知道您正在执行一项智力活动,所以下面这个评论绝对不适用--但对于其他任何人来说,值得注意的是,重新创建诸如List和Collection方法- for -method- method-for-method -for-method-method-for-method,以复制.NET --这一点忽略了TypeScript (和JavaScript)是一种不同的语言这一观点。您的TypeScript程序中的所有数组都是通用的,所以用所有这些不同的方式包装它们几乎没有什么好处--所有这些都只是开销。但正如我所提到的,作为一项智力锻炼,这是很有趣的东西。
https://stackoverflow.com/questions/21382576
复制相似问题