【问题标题】:Is there a way to internally set an object equal to a reference?有没有办法在内部设置一个等于引用的对象?
【发布时间】:2013-05-14 04:53:11
【问题描述】:

假设您有一个名为 Car 的类。现在通常,如果你想设置 Car 的一个实例等于另一个实例,你会这样做:

Car car1 = new Car();
Car car2 = new Car();

car1 = car2;

现在,如果你想要一个方法来做到这一点呢?

Car
{
 public void SetEqualToReference(Car reference)
 {
  this = reference;
 }
}

然后你会这样做

car1.SetEqualToReference(car2);

car1 将等于 car2。 但如你所知,这是行不通的。有没有办法做类似的事情?

【问题讨论】:

  • 将一个 instance 设置为等于另一个的概念根本不存在。在您的第一个代码 sn-p 中,您使一个 variable 与另一个 variable 具有相同的值。这对实例根本没有任何作用。
  • 否;那是彻底的,完全不可能的。几乎。 blog.slaks.net/2010/12/when-can-you-write-ref-this.html
  • @JonSkeet:值类型除外。
  • 你的目标是什么?为什么 car1 = car2 不适合你?
  • 正如其他人所说,您不能分配给thisSetEqualToReference(ref Car reference) { reference = this; } 怎么样?

标签: c# winforms visual-studio-2010


【解决方案1】:

在阅读您关于保存和打开对象的序列化版本是您真正想要做的评论后,我提供了这个答案。

Save 方法总是一样的:

class Car {

  public void Save(String fileName) {
    // Serialize the fields of the current instance to the file.
  }

}

要从序列化数据初始化新实例,您可以使用构造函数:

class Car {

  public void Car(String fileName) {
    // Initialize a new instance from the serialized data in the file.
  }

}

另一种选择是提供静态工厂方法:

class Car {

  public static Car Open(String fileName) {
    var car = new Car();
    // Initialize the new instance from the serialized data in the file.
    return car;
  }

}

重点是“Open”方法不是Car 实例上的方法。它应该是构造函数或静态方法。然后您不必“在内部将对象设置为等于引用”(无论如何这是不可能的)。

在某些方面,您在问题中提出的思路类似于Prototype-based programming。但是,C# 是一种基于类的语言,而不是基于原型的语言。

【讨论】:

    【解决方案2】:

    已经有一种方法可以将引用分配给另一个对象。它被称为 operator=,并在语言中实现为 =,就像您在问题中所写的那样:

    car1 = car2

    Jon Skeet 很好地解释了引用和对象本身之间的区别。我认为您可能对对象和对对象的引用之间的区别缺乏了解,但我可能错了。如果您告诉我们您要做什么以及为什么,我们可能会以更好的方式指导您:)

    根据您的 cmets 更新:

    我建议在 Car 类上创建一个静态工厂方法,如下所示:

    class Car {
    
    public static Car Open(string fileName) {
        return (Car) binaryFormatter.DeSerialize(File.Open(fileName));
    }
    

    然后你可以说:

    Car car = new Car();
    car.Save(fileName);
    car = Car.Open(fileName) // re-reads the car from file
    

    【讨论】:

    • 我想我可能对对象和引用之间的区别缺乏了解。至于我想要做什么,我目前有一个具有保存功能的课程。保存时,它将类的实例保存到具有二进制格式化程序的文件中。所以基本上: MyClass object = new MyClass() object.save();我想要做的是添加一个“打开”函数,它将对象设置为等于它从我之前使用保存函数写入的文件中读取的类。就像 object.Open()
    • 好的,那么,为什么要在使用二进制格式化程序保存对象时更改对对象的引用?如果您提供更多代码(提供更多上下文),也许我们可以提供更好的帮助。
    • 并且在 Open 函数中,它会将自己设置为等于从文件中读取的对象。所以打开函数看起来像 Open(){this = (MyClass)binaryformatter.deserialize(stream)}
    • 好的,我认为最适合您需求的是静态工厂方法,它从文件中读取对象。
    • 它回答了问题的意图。我认为尝试理解和回答人们需要问的问题,而不是回答他们真正问的问题是有价值的(但是,再说一遍,我是一名顾问;))
    【解决方案3】:

    “我想要做的是添加一个“打开”函数,它将对象设置为等于它从我之前使用保存函数写入的文件中读取的类。”

    您可以将 Open() 设为 Car 类的 static 函数,并让它返回一个代表已打开文件的 New 实例:Car c = Car.Open("somefile.txt");,代码如下:

    public class Car
    {
    
        // ... bunch of members for Car ...
    
        public static Car Open(string FileName)
        {
            Car c = new Car();
            // ... open the file and populate "c" ...
            return c;
        }
    
    }
    

    另一个选项是将文件名传递给 Car 的构造函数,它将从那里填充。不过,您需要 Car 中的某种“有效”字段来指示文件打开是否成功。

    【讨论】:

    • 谢谢,我想虽然它并没有真正发生在对象本身的内部。
    • 你是对的......正如其他人已经指出的那样:你不能那样做。另外,我很确定@Martin Liversage 在他的回答中用非常相似的代码击败了我几分钟......
    • 感谢您指出这一点,虽然我并没有真正得到我想要的,因为正如您所说,这是不可能的,信用到期。
    猜你喜欢
    • 1970-01-01
    • 2010-10-27
    • 2020-06-01
    • 1970-01-01
    • 2020-12-02
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多