快速笔记
本文中的代码构建在内部构建的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的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和Present,但这仍然很繁琐,它应该每个对象遍历Update方法一次,以保持与代码其余部分的一致性。
我的思想
我理解static类不能继承class或实现interface,所以我想知道是否有一种方法可以提供static类并以类似的方式调用它的Initialize方法;即使这意味着创建一个单独的方法来完成它。
我现正考虑两个方案:
第一个选项的问题是,我有12个static类,必须更新进度和反馈消息,引发事件,并为每个类重新呈现场景。
第二个选项的问题是,这些static类只包含static属性,因此定义上应该是static,因为不需要从它们继承或创建它们的实例。
问题
是否有一种方法可以跨多个静态类调用公共方法?
object或T ),则可能是调用该方法的一种方法。dynamic类型可以工作(尽管您不能创建static类的实例)?发布于 2018-12-13 13:21:27
我现正考虑两个方案:
第三种折衷方法与上面的第二个想法有关,但使用了一种称为Singleton模式的设计模式。和静态类一样,进程中只能有一个类,每个人都得到相同的东西,但是与静态类不同的是,单例类可以实现接口,甚至可以从其他类下降。
对于这个例子,我将使用接口方法。
public interface IInitializable
{
void Initialize();
}接口所做的就是强制它的实现者有一个Initialize方法。
我的下一步是创建一个Singleton类。有几个规则可以实现Singleton模式。你的课必须密封。它的构造函数必须是私有的。它必须具有返回单个实例的静态方法或属性。该方法/属性必须是线程安全。
我用懒散来帮我做重活。
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;
}您对静态类所做的操作有一些细微的差别。如果Foo是一个静态类,您将调用Foo.Initialize();,就像它是Singleton一样,您将调用Foo.Instance.Initialize();
任何其他方法或属性都很可能是非静态的。
把所有的东西组合在一起,你就可以这样写代码了。您的队列不需要知道它包含哪些类。你其实并不在乎。您只想知道它是否有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.
}
}
}这样,这个类就可以这样使用了。
YourClass yourClass = new YourClass();
yourClass.Enqueue(Foo.Instance);
yourClass.LoadOrUpdate();发布于 2018-12-12 21:59:49
虽然我希望有一个比这更好和更详细的答案;我已经想出了一个基本的解决方案。我创建了一个单独的Queue<Type>,其中添加了static类。然后使用以下方法调用他们的Initialize方法:
Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });这很好,而且相当干净,但我不禁想知道是否有更好的方法来做到这一点?
https://stackoverflow.com/questions/53751764
复制相似问题