代码之家  ›  专栏  ›  技术社区  ›  user1556594

在对象中存储对外部变量的引用

  •  0
  • user1556594  · 技术社区  · 14 年前

    我正在为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#中是否可能出现类似的情况?

    是否应始终避免使用不安全代码?

    编辑:

    --预期用途--

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

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

    具体的应用程序将主要用于游戏中的编辑。我知道编辑器在独立的情况下是最实用的,但这是为了有限的、游戏机友好的编辑功能(不太健壮,但原则上类似于《小星球》的编辑功能)。

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

    谢谢你的回复!

    3 回复  |  直到 14 年前
        1
  •  0
  •   Andrew Russell    14 年前

    在C#中这样做的方法是使用一对get/set委托。您可以使用这个方便的dandy helper结构来存储它们:

    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. 创建这些东西会分配内存。这对性能非常不利,原因有很多。因此,避免在绘制/更新循环中创建这些。不过,在装载过程中是可以的。

    最后,这比直接访问房产更丑陋——所以要确保你在尽你所能 避免 在可能的情况下使用这个。

        2
  •  0
  •   mtijn    14 年前

    如果没有不安全的代码,我不知道如何在C#中做到这一点,但是。。如果你绝对必须用这个解决方案来解决你的问题,并且不使用不安全的代码,那么也许 memory mapped files 是你的朋友。即便如此,这些直到.NET 4.0才出现在.NET开发中,我不确定这个选项与不安全的代码性能相比如何。

        3
  •  0
  •   Felice Pollano    14 年前

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