C# 这个抽象类是否有其他方法从这个泛型类型派生?错误CS0310

C# 这个抽象类是否有其他方法从这个泛型类型派生?错误CS0310,c#,generics,C#,Generics,我有以下几段代码: // The Singleton.cs file. public abstract class Singleton<T> where T : class, new() { private static T _instance; public static T Instance => _instance ?? (_instance = new T()); } // The ScriptEvent.cs file. public abstrac

我有以下几段代码:

// The Singleton.cs file.
public abstract class Singleton<T> where T : class, new()
{
    private static T _instance;

    public static T Instance => _instance ?? (_instance = new T());
}
// The ScriptEvent.cs file.
public abstract class ScriptEvent : Singleton<ScriptEvent>
{
    public abstract void RaiseEvent(params object[] raiseParameters);

    public abstract void Subscribe(Delegate toSubscribe);

    public abstract void Unsubscribe(Delegate toUnsubscribe);

    public abstract Delegate[] GetSubscribers();
}
//Singleton.cs文件。
公共抽象类单例,其中T:class,new()
{
私有静态T_实例;
公共静态T实例=>\u实例??(\u实例=new T());
}
//ScriptEvent.cs文件。
公共抽象类ScriptEvent:Singleton
{
公共抽象void RaiseEvent(参数对象[]raiseParameters);
公开摘要无效认购(委托认购);
公开摘要作废退订(委托退订);
公共抽象委托[]GetSubscribers();
}
我希望ScriptEvent从Singleton派生,因为ScriptEvent必须是Singleton。但是,这给了我一个错误:

Error   CS0310  'ScriptEvent' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Singleton<T>
错误CS0310“ScriptEvent”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“Singleton”中的参数“T”
到目前为止,我能看到的唯一解决方案是直接在ScriptEvent中实现Singleton功能,虽然这可以工作,但我确实觉得不干净/没有必要

我有办法解决这个问题吗?我更愿意将ScriptEvent保持为抽象的,尽管在我写这篇文章的时候,我已经意识到我也可以取消它的抽象并使用虚拟方法。然而,这可能会让这段代码的未来用户感到困惑,因为他们可能会尝试实例化一个ScriptEvent,而这并不是有意的(因此采用了单音化:P和抽象)。我还假设另一个解决方案是使Script TevEnter泛型,并且派生类提供它们自己的类型,类似于SuntLon的工作方式,但是我认为这是非常不理想的,因为我希望避免对派生者造成尽可能多的混淆。 编辑:我已经找到了一个(临时的?)解决我问题的方法。 我使用“断章取义”的方法。我把这个类变成了一个常规类,用几乎相同的虚拟方法替换了所有的抽象方法,但是添加了一个空的静态构造函数来防止实例化!
然而,我仍然想要一个答案,因为我对这个解决方案不太满意。

删除继承。改用类型约束

// The Singleton.cs file.
public abstract class Singleton<T> where T : ScriptEvent, new() //Type constraint
{
    private static T _instance;

    public static T Instance => _instance ?? (_instance = new T());
}

// The ScriptEvent.cs file.
public abstract class ScriptEvent  //No inheritance
{
    public abstract void RaiseEvent(params object[] raiseParameters);

    public abstract void Subscribe(Delegate toSubscribe);

    public abstract void Unsubscribe(Delegate toUnsubscribe);

    public abstract Delegate[] GetSubscribers();
}
//Singleton.cs文件。
公共抽象类Singleton,其中T:ScriptEvent,new()//类型约束
{
私有静态T_实例;
公共静态T实例=>\u实例??(\u实例=new T());
}
//ScriptEvent.cs文件。
公共抽象类ScriptEvent//无继承
{
公共抽象void RaiseEvent(参数对象[]raiseParameters);
公开摘要无效认购(委托认购);
公开摘要作废退订(委托退订);
公共抽象委托[]GetSubscribers();
}
然后,要获取您将使用的实例:

var instance = Singleton<DerivedType>.Instance;
var instance=Singleton.instance;

是否有理由将其作为模板化的单例实现?你在用DI吗?如果是这样,为什么不让DI来处理作用域呢?当您调用
new T()
时,您希望发生什么?当然,您不能实例化ScriptEvent,因为它是抽象的。@JohnWu这是真的!我希望new T()能够有效地“调用new”。有可能吗?@Charleh我不知道你说的“DI”是什么意思。我之所以想将其实现为模板化(“泛型”)单例,是因为我相信这可能会更干净一些。也许这是不正确的。我没有考虑过这种方法,这是非常有帮助的。然而,我认为我将使用ScriptEvent本身是单例(将单例的功能克隆到ScriptEvent)的方法来简化代码。毕竟,我不认为只为ScriptEvent需要单独的类。不管怎样,我还是要感谢你,而且我将来肯定会使用这种方法!