Solved

creating copy constructor for c# child class, need help

Posted on 2014-04-15
5
1,217 Views
Last Modified: 2014-04-15
Hello,

I’m a bit stuck on how to create a copy constructor (correct term?) for my child class, using a parent class from a library, as the source.  The goal is to effectively, “convert” the parent class into the child class, so that my existing code can continue to use variables of this class as the parent class, and new code (with a cast) can use the variable as the Child class.

The Parent class from the library is derived from System.Object, and implements the MemberwiseClone function.  I suspect I want to use this protected function in the copy constructor, but I can’t figure out how.

Unfortunately, I’m not even sure how the parent class is initiated:  I think it is done in some other library class, I can’t even see the call to the parent class’s constructor.

So, the question is: Can this be done without knowing details about the Parent class? And if so, what goes in the child’s copy constructor?

Also, considering the sample usage in the code below, should I be making a Deep Copy, rather than a Shallow Copy? (Not really clear on how to implement a Deep copy either.)

    public class Parent : Object
    {
        //implements: protected Object MemberwiseClone()
        //other-wise: black box from a library
        public void Foo() { };
    }

    public class SomeData
    {
        int i=1;
        string str="a";
        string compute() { return str + i.ToString(); }
    }

    public class Child : Parent
    {
        public SomeData additional_data;

        //define copy constructor
        public Child(Parent source,SomeData _additional_data)
        {
            additional_data = _additional_data;
            //... ??  ...
        }
    }

    public class SampleUsage
    {
        public SampleUsage()
        {
            Parent item = new Parent();
            //...
            //item now initialized by black box
            //...
            SomeData data=new SomeData();
            item=new Child(item,data);  //call copy constructor, overwrite original Parent item with newly created child item
            
            //...later on...
            SomeData data_retrieved;
            data_retrieved= ((Child)item).additional_data;
            
            item.Foo();//I've got many line of codes like this one already in existance- dont want to alter them if possible
        }
    }

Open in new window

0
Comment
Question by:Korbus
  • 3
  • 2
5 Comments
 
LVL 23

Accepted Solution

by:
Jens Fiederer earned 500 total points
ID: 40002323
Copy constructor is a correct term if your only parameter is a member of your class.  It is especially significant in C++, where it is actually provided if not present, and called on your behalf in certain instances.

Your

public Child(Parent source,SomeData _additional_data)
        {
            additional_data = _additional_data;
            //... ??  ...
        }

Open in new window


Using  MemberwiseClone isn't really feasible here because it returns a NEW object rather than initializing elements of an existing one.   Also it returns an object of the same type as its parameter rather than a subclass.

You CAN use reflection for that effect, such as:

        public static void CopyProperties(this object destination, object source)
        {
            PropertyInfo[] destinationInfos = destination.GetType().GetProperties();
            Dictionary<string, PropertyInfo> lookup = new Dictionary<string, PropertyInfo>();
            foreach (PropertyInfo destinationInfo in destinationInfos)
            {
                lookup[destinationInfo.Name] = destinationInfo;
            }
            foreach (PropertyInfo sourceInfo in source.GetType().GetProperties())
            {
                PropertyInfo destinationInfo = null;
                if (lookup.TryGetValue(sourceInfo.Name, out destinationInfo))
                {
                    if (sourceInfo.CanRead && destinationInfo.CanWrite)
                    {
                        destinationInfo.SetValue(destination, sourceInfo.GetValue(source, null), null);
                    }
                }
            }
        }

Open in new window


Deep copies require a bit more work in terms of specific code written or a recursion.  Whether deep copy is more or less appropriate depends on more context than your sample provides...nothing there indicates a deep copy is necessary.
0
 
LVL 10

Author Comment

by:Korbus
ID: 40002836
Thank you Jens,

Looks like an unexpected, but very usable solution.
I tried to test it, and found I had left something out of my OP.

The Parent class does NOT have a default constructor.  (Rather it has a constructor that uses two OTHER classes as parameter types that I'm not familiar with.)

So it appears, I don't even have a way to create a new child class.  :(
The compiler is generating this error:
Error      1      'Parent' does not contain a constructor that takes 0 arguments

Am I out of luck, or missing something?
0
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 40002893
Is this perhaps a Generic Type rather than a real class?  What does it look like?
0
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 40002895
At any rate, you want to change

Parent item = new Parent();

Open in new window


to the appropriate call.
0
 
LVL 10

Author Closing Comment

by:Korbus
ID: 40002967
The parent class is actually Microsoft.Xna.Framework.Content.ContentManager.  
(An instance of ContentManager is passed to various other classes during initialization for their OnLoad functions.  The goal is to include additional data in this instance, so we can customize some OnLoad functions to use this data, without modifying any class structures.  The catch is, some OTHER class is actually instantiating the instance of ContentManager.)

Alas, I don't know about the parameters this class's constructor takes (IServiceProvider).  I think I was hoping to avoid having to deal with that stuff because I already had an instance of the Parent I wanted to work with.

Guess I'll just need to figure out how to call that constructor.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Fluent Interface Design Pattern You can use the Fluent Interface (http://en.wikipedia.org/wiki/Fluent_interface) design pattern to make your PHP code easier to read and maintain.  "Fluent Interface" is an object-oriented design pattern that r…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question