C# struct by-ref

本文关键字:by-ref struct | 更新日期: 2023-09-27 18:19:55

C#中有什么方法可以做到这一点吗:

map.player.x = 5;

同时保持Point类型的player(或静默地可转换为1),并且在执行赋值时仍然能够检查值的正确性?

更清楚地说:

  • Point是由C#/.net标准库定义的结构,并通过值传递
  • 制作一个包装类并将Point的所有方法实现为对Point的调用是漫长而乏味的
  • 有一个包装器类,除了一个到Point的隐式转换之外,什么都不允许。它必须写成(Point)(map.player).x,这很笨拙

C# struct by-ref

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

避免使用可变结构(值类型)。struct Point是旧的Win32 API遗留下来的不幸的东西。

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

否。player变量,在这种情况下,您在赋值过程中没有任何机会验证更改,或者playerproperty。在这种情况中,表达式map.player被归类为并且不允许设置x部分(因为它将是无usless的)。

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

map.SetPlayerX(5);

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

1

同时指定两个坐标怎么样?

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

现在,您可以在播放器属性中拥有验证逻辑。


2

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

有些人建议使用类类型来保存X和Y值。我对这种方法持怀疑态度,并表明在许多情况下,通过将CCD_ 18作为字段公开而获得的语义将更加清晰(尽管我不清楚为什么map有一个名为player的成员。如果map引用了MapType,而MapType的实例有一个结构类型为player的字段,字段类型为integer的x,那么很明显,对map.player.x的更改将影响MapType的一个实例。此外,说map1.player = map2.player;将把字段从map2.player复制到map1.player。相比之下,如果player是类类型一种是map1.player = map2.player; map1.player.x = 5;,这将影响map1map2

是否使用可变结构与可变类的问题很简单,但"如果它是可变的,就把它变成一个类"的概念是完全错误的。只要问问自己,给定:

thing1=thing2;thing1.x=5;

您希望第二条语句影响thing2.x的值吗?如果是,请使用类。如果没有,请使用结构。

顺便说一句,如果你不想让你的地图类型公开player作为字段,另一种模式是让它公开ActOnPlayer方法:

公共委托ActionByRef<T>(参考T p);公共委托ActionByRef<T1、T2>(参考T1 p1、参考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);}…示例用法:地图ActOnPlayer((ref player键入它,ref int参数)->{it.x=参数;},someIntVariable);

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