ts如何创建泛型单例

  • Creator 版本:

  • 目标平台:

  • 详细报错信息,包含调用堆栈:

  • 重现方式:

  • 之前哪个版本是正常的 :

  • 手机型号 :

  • 手机浏览器 :

  • 编辑器操作系统 :

  • 编辑器之前是否有其它报错 :

  • 出现概率:

  • 额外线索:
    刚接触TS,参照C#代码,想用TS实现类似的效果,一直写不出来, 以下是C#代码,

class Singleton where T: class,new()
{
private static T _instance;
private static readonly object syslock=new object();

public static T getInstance()   
{  
    if (_instance == null)  
    {  
        lock (syslock) {  
            if (_instance == null)  
            {  
                _instance = new T();  
            }  
        }  
    }  
   return _instance;  
}  

}
这是我自己写的ts代码, 一直报错:静态成员不能引用类类型参数
export class Singleton{
private static _instance: T;

private constructor(){}

public static getInstance() : T {
    if(this._instance == null) {
        this._instance = new T();
    }
    return this._instance;
}

}
一直没有头绪,希望大家指点指点;

1赞

直接贴代码了

export default class Singleton<T> {
    private static _instance: any = null;
    public static getInstance<T>(type: { new(): T}){
        if (this._instance === null) {
            this._instance = new type();
        }
        return this._instance;
    } 
}

使用时:

Singleton.getInstance<Test>(Test)
4赞

谢谢BigBear,受教了;

如果还有一个单例Test2,那么调用Singleton.getInstance<Test2>(Test2) 的时候不就出问题了?大家都共享了一个_instance

你想通过一个静态类获得多个子类的单例,那你 就存数组呗,

export default class Singleton<T extends Singleton<any>> {
    private static _instance: Singleton<any>[] = null;
    public static getInstance<T>(type: { new(): T }) {
        if (Array.isArray(this._instance)) {
            for (let index = 0; index < this._instance.length; index++) {
                if (this._instance[index] instanceof type) {
                    return this._instance[index];
                }
            }
        }
        else {
            this._instance = [];
        }
        var ret = new type();
        this._instance.push(ret);

        return ret;
    }
}

类的 泛型 是针对类的实例化类型的,静态属性不可以使用泛型类型

你可以把泛型 理解成一个未来类型,而属性的类型定义是即时的

这种单例宁可不用,循环太可怕了

那是楼主的需求,小数组有什么可怕的,如果你非觉得数组是魔鬼。那就存对象呗 let key = cc.js.getClassName(type) 作为键值 _instance[key] = new type()

大佬,我参照你这个写法写了泛型单例,但是子类继承后,我在另外一个脚本调用子类的方法却调用不到,能否指点一下?
链接:小白问一下TS的单例模版怎么写啊 - 3D - Cocos中文社区 https://forum.cocos.com/t/ts/83363/12

@BigBear
public abstract class Singleton : MonoBehaviour where T : Singleton {

	public static T instance { get; protected set; }

	public static bool instanceExists
	{
		get { return instance != null; }
	}

	protected virtual void Awake()
	{
		if (instanceExists)
		{
			Destroy(gameObject);
		}
		else
		{
			instance = (T) this;
		}
	}
}

这个是unity的泛型单例,我试了在ts好像弄不了?

const { ccclass, property } = cc._decorator;
@ccclass
export default abstract class Singleton extends cc.Component {

private static _instance: any = null;

public static get instance() {
    return this._instance;
}

onLoad() {
    Singleton._instance = this as T; // 报错
}

}

提供另外一种思路:

export class TestMgr{}

export module Global {
    export let testMgr = new TestMgr();
}

// 使用
Global.testMgr.***

将所有需要单利的对象都在Global里面创建,这样统了一入口。要知道代码里面有什么单利直接去Global里面看就行。

if (instanceExists)
{
Destroy(gameObject);
}
这种写法好奇怪

我是继承component,这个好像不行,因为new了

@BigBear 大佬在吗