首页 > 解决方案 > 有没有办法强制派生类型声明具有特定签名的静态方法?

问题描述

我需要一种方法来强制我的一个类的子类声明一个特定的静态方法。例如类型安全的 FromFile 或 FromStream 函数。类似于非静态上下文的抽象方法的概念。

我知道我可以使用这样的结构:

return (T)typeof(T).GetMethod("FromFile").Invoke(null, new[] { someArgs });

但是,如果未定义该方法,这只会在运行时引发异常。但是我想要的是使代码不存在时无法编译。

我也知道我可以在启动时获取所有这些加载器方法并将它们存储在静态类型加载器映射中,但它仍然只会在应用程序启动期间抛出异常。

对于这个例子,我使用了一个纹理加载器,只要它们继承相同的基类,它就应该能够加载不同类型的纹理。(OpenGL 纹理包装器、DX 纹理包装器、视频纹理等)

public abstract class DataContainer<T>
{
    public abstract T Load(object someArgs);

    [...]
}

public class TextureContainer<T> : DataContainer<T> where T : Texture<T>
{
    public override T Load(object someArgs)
    {
        if (/*is currently loaded*/)
            return GetLoadedFile(someArgs);
        else
            return T.FromFile(someArgs);
    }

    [...]
}

纹理的基类看起来像这样:

public abstract class Texture<T> where T : Texture<T>
{
    //works fine, forces derived class to declare a type safe Clone method
    public abstract T Clone();

    //sadly for static methods I can't do the same
    //so I need another way here
    public static /*abstract*/ T FromFile(object someArgs);
}

那么纹理的具体实现将如下所示:

public class DirectXTexture : Texture<DirectXTexture>
{
    //works fine
    public override DirectXTexture Clone()
    {
        throw new System.NotImplementedException();
    }

    //another way needed
    public static /*override*/ DirectXTexture FromFile()
    {
        throw new System.NotImplementedException();
    }
}

有了这个设置,您可以简单地通过使用以下代码和基本 DataContainer 加载并在必要时卸载纹理或在后台线程中执行加载任务来获取纹理。

static class Program
{
    static void Main(string[] args)
    {
        var container = new TextureContainer<DirectXTexture>();
        var tex = container.Load("some file");
    }
}

澄清一下:我已经有一个完全正常工作的 DataContainer 构造,它可以在主线程或后台线程中加载资源并监视引用我的资源的实例,这样如果没有人需要它们,我可以卸载它们。我唯一需要的是为 ABSTRACT 类型及其相应的加载方法创建容器的功能,因此我不必为 DXTextureContainer、GLTextureContainer、VideoTextureContainer 等创建单独的子类。

我希望你们能在这里帮助我。提前致谢!

标签: c#-6.0

解决方案


直到C# 8.0都没有办法强制执行。

从 Visual Studio 2017 开始,您可以编写一个 Roslyn 分析器来标记它(如果需要,可以将其设为编译错误),甚至提供修复。


推荐阅读