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
,这很笨拙
如果我理解得对,您似乎希望通过定义类型转换来获得一些灵活性。这不会太远。
避免使用可变结构(值类型)。struct Point
是旧的Win32 API遗留下来的不幸的东西。
所以瞄准map.player = new Point(5, map.player.y);
否。player
是变量,在这种情况下,您在赋值过程中没有任何机会验证更改,或者player
是property。在这种情况中,表达式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;
,这将影响map1
和map2
。
是否使用可变结构与可变类的问题很简单,但"如果它是可变的,就把它变成一个类"的概念是完全错误的。只要问问自己,给定:
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);
请注意,后一种方法看起来类似于使用闭包,但与使用闭包不同,它不会生成任何新的临时堆对象,因此不会给垃圾收集器带来任何压力。