C# · 12月 23, 2021

参考类型的值分配在C#

通过参考类型的值实现分配的正确方法是什么?我想执行一个作业,但不改变引用.

这是我在说的:

void Main(){ A a1 = new A(1); A a2 = new A(2); a1 = a2; //WRONG: Changes reference a1.ValueAssign(a2); //This works,but is it the best way?}class A{ int i; public A(int i) { this.i = i; } public void ValueAssign(A a) { this.i = a.i; }}

我应该用这种惯例吗?我觉得我不是第一个遇到这个的人.谢谢.

编辑:

哇.我想我需要更多地针对我面临的实际问题来定制我的问题.我得到了很多不符合不改变参考要求的答案.克隆不是这里的问题.问题在于克隆克隆.

我有许多依赖于A的课程 – 他们都可以分享对类A的同一个对象的引用.所以,每当一个班级改变A时,它反映在其他的对象中,对吗?这一切都很好,直到一个类尝试这样做:

myA = new A();

实际上,我没有做新的A(),但我实际上正在从硬盘驱动器上检索A的序列化版本.但无论如何,这样做会导致myA接收到新参考.它不再与依赖于A的其他类共享相同的A.这是我正在尝试解决的问题.我希望所有具有A实例的类都受到上面的代码行的影响.

我希望这澄清了我的问题.谢谢.

解决方法 听起来你正在谈论克隆.有些对象会支持(通过 ICloneable),但绝大多数不会.在许多情况下,它无论如何也是无意义的 – 复制FileStream对象是什么意思? ICloneable通常被认为是使用不好的界面,部分原因是它没有指定克隆的深度.

最好是尝试改变思维方式,这样就没有必要了.我的猜测是,你是一个C程序员,而且根本不希望作出任何判断:不要像C那样写C#.您最终会遇到可能无法正常工作的单一C#,可能效率不高,可能对于C#开发人员来说是不直观的.

一个选择是尝试在可能的情况下使类型不可变 – 在这一点上,无论是否有副本都不重要,因为您无法改变对象.这是String所采用的方法,它的效果非常好.在框架中还没有不可变的集合,这只是一个耻辱.

在你的情况下,而不是使用ValueAssign方法,您将具有WithValue,这将返回一个新的实例,只是改变了值. (诚​​然,这是您的案例中唯一可用的值…)我意识到这种复制(除了要改变的属性之外)与我在C#中复制是有些单一的,而是在…之内上课而不是外界决定何时复制.

我怀疑我没有很好地解释这一点,但是我的一般建议是围绕它进行设计,而不是试图明确地复制整个地方.