0

我正在为 XNA 中的游戏编程,并尝试创建一个通用数学对象,并在构建期间提供存储的输出位置。

我的计划是在构造函数中使用 ref ,但我不确定如何在初始调用之后将该引用保存/存储在对象中......

public MathObject(ref float OutParam)
{
    Out = OutParam; // This obviously won't do what I want... But it's where I'd like to do it.
}

在更新中,我想说明输入并让产品修改存储的输出位置:

foreach (MathObject MatOb in MathList)
{
    MatOb.Update(time);
}

这个想法是创建一个模块化数学工具以在整个代码中使用,并将其引导到其他地方的预先存在的对象参数(“输出”),它将在更新中修改(无需重新引用)。希望这将允许一个循环来指导工具的每个实例来修改它的给定输出。

据我了解,在 c++ 中,这可以通过将要修改的参数的地址存储在数学对象中,然后在更新中使用它来指向和修改该位置的内存。

在不使用不安全代码的情况下,在 c# 中是否有类似的可能?

是否应该始终避免不安全的代码?

编辑:

- 有可能的使用 -

我希望能够创建具有可调节“设置并忘记”输出位置的对象。

例如,我构建了一个在游戏界面中工作的简单贝塞尔曲线编辑器。我可以在代码中设置输出位置,以便给定曲线始终调整特定参数(例如字符位置),但也可以在界面中修改输出连接的内容。

特定应用程序主要用于游戏内编辑。我知道编辑器在独立时是最实用的,但这将是有限的,游戏控制台友好的编辑功能(不太强大,但原则上类似于 Little Big Planet 的编辑功能)。

我的背景是 3D 设计和动画,所以我习惯于使用许多基于节点的编辑系统 - 创建各种实用节点并调整输入和输出以驱动阴影、装配模型等参数。我当然不会尝试在游戏中重新创建它,但我很好奇将某些原则应用于有限的游戏内编辑功能。只是排除故障最好去做。

感谢您的回复!

4

3 回答 3

0

如果没有不安全的代码,我不知道如何在 C# 中执行此操作,但是.. 如果您绝对必须使用此解决方案解决您的问题并且不使用不安全的代码,那么内存映射文件可能是您的朋友。即便如此,这些在 .NET 4.0 之前还没有用于 .NET 开发,我不确定这个选项与不安全代码的性能相比如何。

于 2012-07-27T08:31:53.003 回答
0

我认为您需要的是观察者设计模式。对数学对象的更新感兴趣的项目将注册 avent ( ie MathObjectChange) 并做出适当的反应。

于 2012-07-27T08:37:29.700 回答
0

在 C# 中执行此操作的方法是使用一对 get/set 委托。你可以使用这个方便的辅助结构来存储它们:

public struct Ref<T>
{
    Func<T> get;
    Action<T> set;

    public Ref(Func<T> get, Action<T> set)
    {
        this.get = get;
        this.set = set;
    }

    public T Value { get { return get(); } set { set(value); } }
}

给定这样的类:

class Foo { public float bar; }

像这样使用它:

Foo myFoo = new Foo();
Ref<float> barRef = new Ref<float>(() => myFoo.bar, (v) => myFoo.bar = v);

// Ta-Da:
barRef.Value = 12.5f;
Console.WriteLine(barRef.Value);

(请注意,我还没有实际测试过这里的代码。这个概念很有效,而且我之前已经成功使用过它,但是我可能会通过在我的头顶上输入这个来搞乱我的语法。)

因为这个问题是用 XNA 标记的,所以我应该简单地谈谈性能:

  1. 您可能会发现它的执行速度比等效的内存访问慢一个数量级左右——因此它不适合紧密循环。

  2. 创建这些东西会分配内存。由于多种原因,这对性能非常不利。所以避免在你的绘制/更新循环中创建这些。不过,在加载过程中很好。

最后,这比简单地直接访问属性更难看——所以请确保你正在尽你所能避免在可能的情况下使用它。

于 2012-07-27T09:06:27.727 回答