5

I apologize for asking something that is probably too basic for C# folks. I'm mostly doing my coding in C++.

So if I want to write an assignment constructor for my class, how do I do that? I have this so far, but it doesn't seem to compile:

public class MyClass
{
    public string s1;
    public string s2;
    public int v1;

    public MyClass()
    {
        s1 = "";
        s2 = "";
        v1 = 0;
    }

    public MyClass(MyClass s)
    {
        this = s;    //Error on this line
    }
}


MyClass a = new MyClass();
MyClass b = new MyClass(a);
ahmd0
  • 16,633
  • 33
  • 137
  • 233
  • 1
    That's not possible for a class. It's possible for a struct. All classes in C++ are effectively structs in C#, in that all classes and structs in C++ are value types, not reference types. – Servy Aug 08 '13 at 19:10
  • that doesn't make sense for a reference type (`class`). – Federico Berasategui Aug 08 '13 at 19:11
  • Ugh. What an abuse of a beautiful language. You C++ guys should be ashamed of yourselves for stuff like that. –  Aug 08 '13 at 19:12
  • Be careful! Objects in C# aren't value types, like in C++. You can think of `MyClass a = new MyClass();` more like `shared_ptr a(new MyClass());` – dss539 Aug 08 '13 at 19:18
  • @dss539: Yeah. I learned it the hard way. Also `sizeof` is not what `sizeof` is in C++, to name a few. I don't know why they couldn't call it something else! – ahmd0 Aug 08 '13 at 19:24
  • It's also useful to know that C# `struct` *is* a value type. Another thing that might trip you up is finalization. The typical class pretty much never needs a method like `~MyClass(){ /* cleanup */ }` because that is ONLY *ONLY* **ONLY!** used to free native win32 resources (window handles, GDI objects, etc). Most native win32 resources are already wrapped in .NET classes for you, so you don't need to write a finalizer. – dss539 Aug 09 '13 at 19:55

4 Answers4

8

You can't assign the class itself - a constructor of that form will typically copy members of the other class:

public MyClass(MyClass s)
{
    this.s1 = s.s1;
    this.s2 = s.s2;
    this.v1 = s.v1;
}

That gives you a "copy" by value of the items in your other class. If you want to have the reference shared, you can't do that, but you wouldn't need a constructor - assigning the variables works fine for that:

var orig = new MyClass();
var referencedCopy = orig; // Just assign the reference
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • It's my understanding that he wanted the result of his code above to be `a` and `b` both being a reference to the same single object. This wouldn't do that. – Servy Aug 08 '13 at 19:13
  • @Servy Not sure if that's the case - edited to include that too – Reed Copsey Aug 08 '13 at 19:15
  • @Servy: No. He is correct. I need separate objects. I guess, this is all very confusing for a person who is used to dealing with pointers and not implied references like in C#. – ahmd0 Aug 08 '13 at 19:15
  • 1
    @Servy, a "copy constructor" duplicates the data contained in the object – dss539 Aug 08 '13 at 19:15
2

What you are trying to do can be achieved using Clone

public class MyClass : ICloneable
{
    public string s1;
    public string s2;
    public int v1;

    public MyClass()
    {
        s1 = "";
        s2 = "";
        v1 = 0;
    }

    public Object Clone()
    {
        return this.MemberwiseClone();
    }
}

Consuming:

MyClass a = new MyClass();
MyClass b = (MyClass)a.Clone();
PhilHdt
  • 320
  • 2
  • 6
  • 1
    You have the MemberwiseClone method in every class, since it is defined in the Object class – PhilHdt Aug 08 '13 at 19:35
  • It is a protected method, you can only access it from the inside of your class. I've updated my answer with the code. – PhilHdt Aug 08 '13 at 20:27
  • Thank you. That is a quick way of doing it, although when I read on it, it says that it creates a `shallow copy` which, if I'm not mistaking, not exactly what I need. I need a new copy of each member object. – ahmd0 Aug 08 '13 at 20:42
  • 1
    If you have only primitive attributes then your class the memberwiseclone is enough, but for a complete cloning you'll need to write a deep clone method, more about that on this [thread](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically) – PhilHdt Aug 08 '13 at 20:55
1

You can't assign this in a class type. The best way is probably to create another constructor and call that:

public MyClass() : this(string.Empty, string.Empty, 0) { }

public MyClass(MyClass s) : this(s.s1, s.s2, s.v1) { }

private MyClass(string s1, string s2, int v1)
{
    this.s1 = s1;
    this.s2 = s2;
    this.v1 = v1;
}
Lee
  • 142,018
  • 20
  • 234
  • 287
1

is this not a reasonable solution?

public myClass() { 
  s1 = ""; 
  s2 = ""; 
  v1 = 0; 
}
public myClass(String _s1, String _s2, Int _v1) {
  s1 = _s1;
  s2 = _s2;
  v1 = _v1;
}

then from your code

myClass a = new myClass();
myClass b = new myClass(a.s1,a.s2,a.v1);
Mr.Monshaw
  • 450
  • 2
  • 7