如何在类之间传递对象

5
我在这里试图将一个类(class A)的副本传递给另一个类(class B),但是class B是在class A中实例化的。在class B中使用new语句是行不通的,因为它会导致无限循环,同时创建第二个实例,而我想要能够使用class A的第一个实例中的变量。我知道有关object.equals()的内容,但是在定义class B中的class A对象之前无法使用它。只是使用object.equals会导致空引用。
public partial class class_A : Form
{
    public class_B _class_B = new class_B;
    public Int32 var; 

    private void setclassA()
    {
        _class_B._class_A.equals(this);
    }
}

public class class_B
{
    public class_A _class_A;        // I know this is null
    // code
}

正如我所说,我希望避免实例化类A的新副本,因为我想要设置类A中的值。

我尝试使用方法来实现,但仍然出现空引用。


4
你完全误解了 Equals() 方法。 - SLaks
6
“class_B._class_A = this” 是正确的方式,“Equals”是用来检查两个实例是否相等的(但在这种情况下它们不可能相等)。 - Ron Beyer
1
顺便说一下,当您发布代码示例时,请确保它可以编译。这有助于我们复制代码并调试您的问题,而不是糟糕的代码。这里有很多东西无法编译,也永远无法编译。 - Ron Beyer
1
在对象完成之前发布其引用,例如将此引用传递给其他对象的构造函数,这是违反原则的。 - Péter
4个回答

4
B的构造函数中传递A:
public class A
{
   private B _b;

   public A()
   {
       _b = new B(this);
   }
}

public class B
{
    private A _a;

    public B(A a)
    {
        _a = a;
    }
}

正如评论中所提到的,你完全误解了 .Equals() 的作用。它是用来比较两个对象是否相等,而不是克隆/传递引用。


谢谢。问题已解决。 - Shaken_U

3

回答

你已经完成了75%的工作。正如Ron所提到的,只需将.equals(this)更改为= this,具体方法如下:

_class_B._class_A = this;

解释

如果我们想要将ClassA的同一份副本传递给ClassB,并在实例化ClassB时在ClassA内部执行此操作,则使用this关键字,该关键字表示类的当前实例。

虽然还有其他方法可以将this传递给ClassB,但下面的示例显示了两种:

  1. this传递给构造函数并在ClassB中进行属性分配或
  2. 直接将this赋值给ClassB中的属性。

对于您来说,关键是=是一个赋值运算符,而Equals()检查两个变量是否引用相同的对象。

示例

public class ClassA
{
    public ClassB MyClassB1 { get; set; }
    public ClassB MyClassB2 { get; set; }

    public ClassA()
    {
        // pass `this` to the constructor
        this.MyClassB1 = new ClassB(this);

        // pass `this` directly to a property in `ClassB`
        this.MyClassB2 = new ClassB();
        this.MyClassB2.MyClassA = this;
    }
}

public class ClassB
{
    public ClassA MyClassA { get; set; }

    public ClassB() { }

    public ClassB(ClassA classA)
    {
        // do property assignment in the constructor
        this.MyClassA = classA;
    }
}

概念验证

此处可运行演示,并输出“它们是同一个对象”以及其他一些内容(在较新版本中)。

using System;   
public class Program
{
    public static void Main()
    {
        var classA = new ClassA();

        if(classA.Equals(classA.MyClassB1.MyClassA) &&
           classA.Equals(classA.MyClassB2.MyClassA) &&
           classA.MyClassB1.MyClassA.Equals(classA.MyClassB2.MyClassA))
        {
            Console.WriteLine("They are the same object.");
        }
    }
}

需要注意的是,当我们这样做时,我们给ClassB一个指向ClassA的引用,而不是它的副本。这两者是非常不同的。


0

试试这个:

public class A
{
    public B Instance_B;

    public A(B b)
    {
         Instance_B = b;
    }
}

public class B
{
    public A Instance_A;

    public B()
    {
         Instance_A = new A(this);
    }
}

4
如果你想教授良好的编程实践,应该使用公共属性而不是公共字段。 - Daniel Mann

-2

使用 get; set;

A 类 中:

public partial class class_A : Form
{
    Class_B B = new Class_B();
    B.Class_A = this;
    public Int32 var;
}   

然后在 B类 中:

public class class_B
{
    Class_A A { get; set; }
    // code
}

这是一种方法,但仅使用get;set;(属性)并不能解决或改变实际问题。 - Ron Beyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接