跨多个静态类调用通用方法吗?

时间:2018-12-12 21:38:51

标签: c# generics static-methods

快速笔记

本文中的代码建立在内部DirectX-11引擎之上,这意味着它遵循以下严格的模式:

Initialize
while (Running) {
    Update
    Render
}

但是,不要让这吓倒您,因为问题与DirectX代码无关,而与static类和方法无关。


概述

我有一个名为RenderObject的类,其中包含一个名为Initialize的方法。此方法负责构建对象的网格,分配纹理,着色器等。

public class RenderObject {
    public virtual void Initialize() { }
}

我还有一些static类,它们包含可重复使用的资源,例如常见的纹理,着色器,模型和网格。这样,我不必稍后重新加载它们。所有这些static类还包含一个名为Initialize的方法,该方法负责创建这些可重用资产。对于这个问题,我将只限于Textures类。

public static class Textures {
    public static Texture2D Dirt { get; private set; }
    public static Texture2D Grass { get; private set; }
    public static void Initialize() {
        Dirt = new Texture2D(...);
        Grass = new Texture2D(...);
    }
}

最后,我有一个名为LoadingSystem的类,该类负责加载可重用资产和初始化对象。我在引擎的Initialize方法内部初始化该类,然后分别在引擎的Update方法中调用该类的Update方法。 LoadingSystem的{​​{1}}方法负责使用Update加载和初始化对象,这对提供平滑的视觉反馈很有用。

Queue

问题

我想用与 public class LoadingSystem { public bool Loading { get; private set; } = true; private Queue<RenderObject> objectsToRender; public void AddForLoad(RenderObject obj) => objectsToRender.Enqueue(obj); public void Update() { if (objectsToRender.Count > 0) { RenderObject obj = objectsToLoad.Dequeue(); obj.Initialize(); } else Loading = false; } } 队列相同的过程在这些Initialize类上调用方法static。目前,我不得不这样做:

RenderObject

我将其简化为处理消息的重复设置并调用CurrentMessage = "Loading Textures"; Render(); Present(); Textures.Initialize(); Progress = ++objectsLoaded / objectsToLoad; CurrentMessage = "Loading Shaders"; Render(); Present(); Shaders.Initialize(); Progress = ++objectsLoaded / objectsToLoad; CurrentMessage = "Loading Models"; Render(); Present(); Models.Initialize(); Progress = ++objectsLoaded / objectsToLoad; Render的方法,但这仍然很繁琐,应该通过{{1} }方法每个对象一次,以与其余代码保持一致。


我的想法

我了解到Present类不能从Update继承或实现static,所以我想知道是否有一种方法可以提供class类并进行调用其interface方法以类似的方式;即使这意味着创建一个单独的方法来完成它。

我目前考虑了两种选择:

  • 分别加载静态类。
  • 将静态类转换为实例类,并与队列一起调用。

第一个选项的问题是我有12个static类,并且必须更新进度和反馈消息,引发事件并为每个场景重新渲染场景。

第二个选项的问题在于,这些Initialize类仅包含static个属性,因此根据定义,它们应该为static,因为无需继承它们或创建一个他们的实例。


问题

是否可以在多个静态类之间调用通用方法?

  • 如果方法存在诸如staticstatic之类的通用类型,该方法是否可以调用该方法?
  • 也许object类型可以工作(尽管您不能创建T类的实例)?

2 个答案:

答案 0 :(得分:1)

  

我目前考虑了两种选择:

     
      
  • 分别加载静态类。
  •   
  • 将静态类转换为实例类,并与队列一起调用。
  •   

第三种折衷方法与上述第二个想法有关,但是使用一种称为“单例模式”的设计模式。像静态类一样,您的过程中只能有一个,每个人都会得到相同的东西,但是与静态类不同,Singletons可以实现接口,甚至可以继承其他类。

在此示例中,我将使用接口方法。

def function(salary):
    year_salary = salary * 12
    return year_salary

接口的所有作用是强制其实现者具有Initialize方法。

我的下一步是创建Singleton类。有几个规则可以实现Singleton模式。您的课程必须被密封。它的构造函数必须是私有的。它必须具有静态方法或属性才能返回单个实例。该方法/属性必须是线程安全的。

我曾经用Lazy为我做繁重的事情

public interface IInitializable
{
    void Initialize();
}

与静态类所做的操作有一些细微的差异。如果Foo是静态类,则您将调用public sealed class Foo : IInitializable { public void Initialize() { // Initialize my foo } private Foo() { } private static Lazy<Foo> fooLazy = new Lazy<Foo>(() => new Foo()); public static Foo Instance => fooLazy.Value; } ,因为它是Singleton,因此您将调用Foo.Initialize();

任何其他方法或属性很可能都是非静态的。

将它们全部拉在一起,您可以编写这样的代码。您的队列不需要知道其拥有的类。你其实不在乎。您只想知道它具有Initialize()方法

Foo.Instance.Initialize();

然后可以像这样使用此类

   public class YourClass
    {
        private Queue<IInitializable> objectsToLoad = new Queue<IInitializable>();

        public void Enqueue(IInitializable obj)
        {
            this.objectsToLoad.Enqueue(obj);
        }

        public void LoadOrUpdate()
        {
            // Update Method
            if (objectsToLoad.Count > 0)
            {
                IInitializable obj = objectsToLoad.Dequeue();
                obj.Initialize();
            }
            else
            {
                // Loading complete.
            }
        }
    }

答案 1 :(得分:0)

尽管我希望有比这更好,更详细的答案;我已经提出了一个基本的解决方案。我创建了一个单独的Queue<Type>,在其中添加了static类。然后,使用以下代码调用其Initialize方法:

Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });

这很好用,很干净,但是我不禁怀疑是否有更好的方法?