Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1409
  • Last Modified:

creating copy constructor for c# child class, need help

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
Korbus
Asked:
Korbus
  • 3
  • 2
1 Solution
 
Jens FiedererCommented:
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
 
KorbusAuthor Commented:
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
 
Jens FiedererCommented:
Is this perhaps a Generic Type rather than a real class?  What does it look like?
0
 
Jens FiedererCommented:
At any rate, you want to change

Parent item = new Parent();

Open in new window


to the appropriate call.
0
 
KorbusAuthor Commented:
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 does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now