存储对象内外部变量的引用

时间:2012-07-27 06:11:54

标签: c# xna

我正在为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设计和动画,所以我习惯于使用许多基于节点的编辑系统 - 创建各种实用程序节点并调整输入和输出以驱动着色,装配模型等参数。我当然是并没有试图在游戏中重新创建它,但我很好奇将某些原则延续并应用于有限的游戏内编辑功能。只是故障排除最好去做。

感谢您的回复!

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我认为你需要is the observer design pattern。对数学对象更新感兴趣的项目将注册avent(即MathObjectChange)并做出正确反应。

答案 2 :(得分: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);

(请注意,我实际上没有在这里测试过代码。这个概念有效,我以前成功地使用过它,但是我可能通过在脑海中输入它来搞砸了我的语法。)< / p>

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

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

  2. 创建这些东西会分配内存。出于多种原因,这对性能非常不利。因此,请避免在绘制/更新循环中创建这些内容。但在加载期间很好。

  3. 而且,最后,这比直接访问该属性更加丑陋 - 所以请确保您尽可能避免尽可能地使用该属性。