Is this a good way to copy a class? [closed]
Asked Answered
G

1

2

I am a complete noob, so let me know if I am out of place for asking this, and if needed give me the boot. Anyways... I have been learning about value types and reference types and am wondering if defining an additional constructor such as this (and then calling it later) is a valid way to create a copy of a class. I tried testing it with a simple class and it seemed to work.

public ClassClass(ClassClass exampleClass)
    {
        var1 = exampleClass.var1;
        var2 = exampleClass.var2;
        // ...
    }

...

Grogram answered 25/9, 2018 at 4:34 Comment(6)
https://mcmap.net/q/10233/-how-can-i-copy-an-instance-of-a-class-in-cFibrillation
It seems fine, but you've only posted partial code. You should provide us with a minimal reproducible example so that we can properly comment on your proposition.Nombles
thanks for the comments! that helped out Jake, i guess i missed that in my search before asking the question.Grogram
i will keep that in mind Enigmativity!Grogram
This for sure is a duplicate of about 100 well answered questionsLastditch
Note that while one usually makes a difference between a shallow vs. deep copy, there actually is no such thing a 'deep copy'..! Instead it is up to you to decide on the depth of your copy, ie how many levels of references you copy process needs to follow!Motif
C
9

There are two kinds of copying objects.

  1. reference copy
  2. value copy

to copy an object by reference you can just use '=' operator.

e.g:

var o1 = new ClassClass();
var o2 = o1;

to copying an object by value, there are several ways, such as:

Copy by a constructor (as you wrote)

    public class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Student(Student std)
        {
            FirstName = std.FirstName;
            LastName = std.LastName;
        }
    }

Make a helper class an pass the s1 as input and return s2 as result

    static void Main(string[] args)
    {
        var s1 = new Student();
        var s2 = ClassHelper.CopyObject(s1);

    }

    public static class ClassHelper
    {
        public static Student CopyObject(Student std)
        {
            var newStudent = new Student()
            {
                FirstName = std.FirstName,
                LastName = std.LastName
            };
            return newStudent;
        }
    }

Generic Copy Objects (using Refelection)

private static void CopyClass<T>(T copyFrom, T copyTo, bool copyChildren)
{
    if (copyFrom == null || copyTo == null)
        throw new Exception("Must not specify null parameters");

    var properties = copyFrom.GetType().GetProperties();

    foreach (var p in properties.Where(prop => prop.CanRead && prop.CanWrite))
    {
        if (p.PropertyType.IsClass && p.PropertyType != typeof(string))
        {
            if (!copyChildren) continue;

            var destinationClass = Activator.CreateInstance(p.PropertyType);
            object copyValue = p.GetValue(copyFrom);

            CopyClass(copyValue, destinationClass, copyChildren);

            p.SetValue(copyTo, destinationClass);                  
        }
        else
        {
            object copyValue = p.GetValue(copyFrom);
            p.SetValue(copyTo, copyValue);
        }
    }
}

Write an extension method for this class and I recommended to do this.

public static class ExtensionClass
{
    public static Student CopyAsNewObject(this Student std)
    {
        var newStudent = new Student()
        {
            FirstName = std.FirstName,
            LastName = std.LastName
        };
        return newStudent;
    }
}

    static void Main(string[] args)
    {
        var s1 = new Student();
        var s2 = s1.CopyAsNewObject();
    }
Canula answered 25/9, 2018 at 4:43 Comment(2)
Note: you're right that using the '=' operator will do a reference copy, but only with reference types (classs). With value types (structs), it'll do a shallow copy.Villiform
nice, you right, it depends on the type of object.Canula

© 2022 - 2024 — McMap. All rights reserved.