Solved

creating copy constructor for c# child class, need help

Posted on 2014-04-15
5
1,176 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
Comment Utility
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
Comment Utility
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
Comment Utility
Is this perhaps a Generic Type rather than a real class?  What does it look like?
0
 
LVL 23

Expert Comment

by:Jens Fiederer
Comment Utility
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
Comment Utility
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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

One of the most frequent problems a "newbie" developer may encounter is having to deal with different data formats. One for all: THE DATE We, as humans, need to "see" a date and then interpret it (much of the times this is an automatic operation)…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

772 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now