Chr*_*lla 3 generics singleton design-patterns typescript
我有一个通用类型,它将作为事件系统中事件的基类。我们希望它们是单例,但它也是通用的,以便子类可以在事件触发时指定他们在回调中期望的参数类型。
我所拥有的看起来像这样:
export interface IEvent { }
export interfact IEventArg { }
export abstract class Event<TEvent extends IEvent, TEventArg extends IEventArg> implements IMessageHandler {
private static s_instance : any;
private static s_isInitializing : boolean;
constructor() {
if (!Event.s_isInitializing)
throw new Error ("Use the GetInstance method to get this class instance.");
}
public static GetInstance<TEvent extends IEvent, TEventArg extends IEventArg>(type: { new() : T; }) : TEvent {
if (!s_instance) {
s_isInitializing = true;
s_instance = new type();
s_isInitializing = false;
}
return s_instance;
}
}
export class SelectionEvent extends Event<SelectionEvent, EmptyEventArg> {
...
}
var event = SelectionEvent.GetInstance(SelectionEvent);
Run Code Online (Sandbox Code Playgroud)
这里有一些东西我认为很奇怪,主要是因为 Typescript 语言的要求。GetInstance 的参数似乎是必要的,因为var x = new TEvent()TypeScript 似乎不允许。空接口有助于强制执行可以接受为泛型类型的内容。
这里似乎不起作用的是静态变量和泛型类型的组合。GetInstance 方法中的块是我想要做的,但显然它无法编译。我还担心静态实例变量不会为每个事件创建一次,而是仅为每个事件实例创建一次,因此会被覆盖。
这里的任何指导将不胜感激。
在 C# 中,泛型类的每个实例化(类型参数集)都有自己的静态成员集。这意味着您可以编写一种单例模式,其中有一个 for 实例Foo<int>,另一个 for 实例Foo<string>,依此类推。这是可能的,因为泛型是在运行时显现的——运行时系统实际上知道泛型是什么,并且可以为每个类型实例化分配新对象。此外,类的静态端可以引用该类的类型参数(这是运行时语义的结果)。
在 TypeScript 中,情况并非如此。每个类只有一个构造函数,无论是泛型还是其他类。这意味着类的静态部分无法“看到”泛型类型参数,因为对于任何类X<T>具有静态成员的类y,只有一个运行时槽X.y。
类的单例模式通常不太适合 TypeScript;请参阅如何在 TypeScript 中定义 Singleton。我想你有一些XY 问题,因此如果没有有关您的用例的更多信息(也许发布一个单独的问题),我无法推荐任何具体的替代方案。
另外,TypeScript 中永远不应该有空接口。类型在结构上进行比较,因此任何两个空类型都是兼容的,并且您可以将任何内容分配给类型为空接口的变量。
| 归档时间: |
|
| 查看次数: |
5653 次 |
| 最近记录: |