0

Say you have a class called Car. Now normally, if you wanted to set an instance of Car equal to another instance, you'd do this:

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

car1 = car2;

Now what if you wanted to have a method that did that?

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

And then you'd do

car1.SetEqualToReference(car2);

And car1 would be equal to car2. But as you know, that doesn't work. Is there a way to do something similar?

  • 3
    The concept of setting one *instance* equal to another simply doesn't exist. In your first code snippet you're making one *variable* have the same value as another *variable*. That does nothing to the instances at all. – Jon Skeet May 13 '13 at 20:29
  • 1
    No; that is thoroughly, completely impossible. Almost. http://blog.slaks.net/2010/12/when-can-you-write-ref-this.html – SLaks May 13 '13 at 20:29
  • @JonSkeet: Except for value types. – SLaks May 13 '13 at 20:29
  • @SLaks: Well, sort of. It's still setting the value of one variable to be the same as the value of the other variable. I think it's easiest to keep differentiating between variables and their values. – Jon Skeet May 13 '13 at 20:31
  • can you tell us why you would want to do this? – Alex Gordon May 13 '13 at 20:32
  • This is impossible: `this = reference;` (for reference types, for a struct it would work) – Tim Schmelter May 13 '13 at 20:32
  • 1
    What is your goal? Why does car1 = car2 not work for you? – sammy_winter May 13 '13 at 20:33
  • 1
    As others said, you can't assign to `this`. How about `SetEqualToReference(ref Car reference) { reference = this; }`? – Buu May 13 '13 at 20:34
  • @BuuNguyen: You can assign to _this_, but only with `structs` and not with reference types. http://stackoverflow.com/a/69988/284240 – Tim Schmelter May 13 '13 at 20:36

3 Answers3

2

After reading your comment that saving and opening a serialized version of your object is what you really want to do I provide this answer.

The Save method is always the same:

class Car {

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

}

To initialize a new instance from the serialized data you can use a constructor:

class Car {

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

}

Another option is to provide a static factory method:

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;
  }

}

The main point is that the "Open" method is not a method on a Car instance. It should either be a constructor or a static method. Then you don't have to "internally set an object equal to a reference" (which isn't possible anyway).

In some ways the line of thought you have presented in your question is similar to Prototype-based programming. However, C# is a class-based language as opposed to a prototype-based language.

Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
1

There's already a method for assigning a reference to another object. It's called operator=, and is implemented as = in the language, like you write in your question:

car1 = car2

Jon Skeet explains beautifully the difference between references and objects themselves. I think that you may have a lacking understanding of the difference between objects and references to objects, but I might be wrong. If you tell us what you are trying to do and why, we could probably guide you in a better way :)

Update based on your comments:

I would suggest creating a static factory method on the Car class, something like this:

class Car {

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

And then you could say:

Car car = new Car();
car.Save(fileName);
car = Car.Open(fileName) // re-reads the car from file
Erik A. Brandstadmoen
  • 10,430
  • 2
  • 37
  • 55
  • I think I may have a lack of understanding between the difference between objects and references. Well as for what I want to do, I currently have class that has a save function. When it saves, it saves the instance of the class to a file with binary formatter. So basically : MyClass object = new MyClass() object.save(); What I want to do is add an "open" function where it sets the object equal to the class it reads from the file I wrote to with the save function earlier. So like object.Open() – CsharpFrustration May 13 '13 at 20:36
  • OK, so, why do you want to change the reference to the object as part of saving it with a binary formatter? If you provide more code (giving a bit more context), maybe we can help better. – Erik A. Brandstadmoen May 13 '13 at 20:38
  • And in the Open function it would set itself equal to the object it read from the file. So the open function would look like Open(){this = (MyClass)binaryformatter.deserialize(stream)} – CsharpFrustration May 13 '13 at 20:40
  • Ok, I think what would best suit your needs, is a static Factory Method, which reads an object from file. – Erik A. Brandstadmoen May 13 '13 at 20:41
  • It answers the intent of the question. I think trying to understand and answer what people need to ask instead of answering what they really ask is valuable (but, then again, I'm a consultant ;)) – Erik A. Brandstadmoen May 13 '13 at 20:47
0

"What I want to do is add an "open" function where it sets the object equal to the class it reads from the file I wrote to with the save function earlier."

You could make Open() a static function of class Car and have it return a New instance that represents the opened file: Car c = Car.Open("somefile.txt"); with code like this:

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;
    }

}

Another option is to pass the filename to the Constructor of Car and it will populate from there. You'd need some kind of "valid" field in Car, though, to indicate whether the opening of the file was successful or not.

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • Thanks I guess this works altough it's not really happening internally inside the object itself. – CsharpFrustration May 13 '13 at 20:58
  • You're right...as the others already pointed out: You can't do that. Also, I'm pretty sure @Martin Liversage beat me by several minutes with very similar code in his answer... – Idle_Mind May 13 '13 at 21:00
  • Thanks for pointing that out, although I didn't really get what I wanted, since as you said, it's not possible, credit where credit's due. – CsharpFrustration May 13 '13 at 21:02