Improve company productivity with a Business Account.Sign Up

x
?
Solved

creating copy constructor for c# child class, need help

Posted on 2014-04-15
5
Medium Priority
?
1,513 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 2000 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

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This article describes and provides a custom-made tool I wrote to give businesses a means of identifying commercial music content, without having to expend too much effort. Business recordings are easily identified from possibly illegal music files …
From store locators to asset tracking and route optimization, learn how leading companies are using Google Maps APIs throughout the customer journey to increase checkout conversions, boost user engagement, and optimize order fulfillment. Powered …
Watch the video to know the simple way to remove or recover or reset lost or forgotten passwords of Outlook PST file. With Kernel Outlook Password Recovery tool such operation is very easy to perform. It is a freeware with limitation to use with 500…

606 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