C#struct by-ref

时间:2012-01-08 20:15:36

标签: c# .net struct ref

C#中是否有任何方法可以执行此操作:

map.player.x = 5;

同时保持player类型Point(或者可以无声转换为1),并且在执行分配时仍然能够检查值是否正确?

更清楚:

  • Point是由C#/ .net标准库定义的结构,并按值传递。
  • 制作一个包装类并将所有Point的方法实现为Point的调用是漫长而乏味的。
  • 拥有一个只包含隐式转换为/ Point的包装类将不允许上述内容。它必须写成(Point)(map.player).x,这是笨拙的。

4 个答案:

答案 0 :(得分:6)

如果我理解正确,您似乎希望通过定义类型转换来获得一些灵活性。这不会走得太远。

避免使用可变结构(值类型)。 struct Point是旧版Win32 API中不幸的遗留问题。

所以瞄准map.player = new Point(5, map.player.y);

答案 1 :(得分:4)

没有。 player变量,在这种情况下,您无法在分配期间验证更改,或player属性,在这种情况下,表达式map.player被归类为,并且您不允许设置x部分(因为它将是无用的)。

我建议你创建一个方法,这样你就可以调用:

map.SetPlayerX(5);

...或者您更改x类所拥有的较大操作的Player值部分。这可能是一种更为面向对象的方法 - 通常如果您发现自己想要做这样的事情,那么值得看看设计和责任。

答案 2 :(得分:1)

1

如何同时分配两个坐标?

map.player = new Point(5, 7);

现在您可以在播放器属性中包含验证逻辑。


2

你真的需要实现System.Drawing.Point的所有内容吗?仅使用您真正需要的东西来实现自己的版本应该不会太困难。 Point中没有太多逻辑。

答案 3 :(得分:1)

有些人建议使用类类型来保存X和Y值。我对这种方法持谨慎态度,并建议在很多情况下通过将player作为一个字段暴露得到的语义会更清晰(尽管我不清楚为什么map有一个名为{{1}的成员如果player引用mapMapType的实例具有结构类型MapType的字段,则字段player的类型为整数很明显,对x的更改会影响map.player.x的一个实例。另外,说MapType会将字段从map1.player = map2.player;复制到map2.player。相反,如果map1.player属于班级类型且其中一个属于player,则会影响map1.player = map2.player; map1.player.x = 5;map1

是否使用可变结构与可变类的问题非常简单,但“如果它是可变的使它成为一个类”的概念是完全错误的。给自己一个问题:

  thing1 = thing2;
  thing1.x = 5;

您希望第二个语句影响map2的值吗?如果是,请使用课程。如果不是,请使用结构。

顺便说一句,如果你不希望你的地图类型公开thing2.x作为一个字段,那么要考虑的另一种模式是让它暴露一个ActOnPlayer方法:

  public delegate ActionByRef<T>(ref T p);
  public delegate ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);

  public void ActOnPlayer(ActionByRef<playerType> proc;)
  {
    proc(ref _player);
  }
  public void ActOnPlayer<T>(ActionByRef<playerType,T> proc, ref T param;)
  {
    proc(ref _player, ref param);
  }
... sample usage:
  map.ActOnPlayer((ref playerType it, ref int theParam) ->
    {it.x = theParam;}, someIntVariable);

请注意,后一种方法看起来就像使用闭包,但与使用闭包不同,它不会生成任何新的临时堆对象,因此不会对垃圾收集器造成任何压力。