Initialize base class in .NET

16,752

Solution 1

Unfortunately base is readonly.

[Edit]
Well perhaps not so unfortunate. The relationship between a base class and a child class is IS-A not HAS-A. By allowing a child class to change the instance of the base class you are allowing the child class to change its own reference since it IS-A base class. If you truly need this functionality then I would suggest you change your inheritance model to reflect what you truly want to do.

Something like this:

public class A
{
    public string field1;
    public string field2;
}

public class B
{
    public string field3;
    public A a;

    public void Assign(A source)
    {
        this.a = source;
    }
}

seems more appropriate and has clearer meaning and functionality.

Solution 2

        public Assign(A a)
        {
            foreach (var prop in typeof(A).GetProperties())
            {
                this.GetType().GetProperty(prop.Name).SetValue(this, prop.GetValue(a, null),null);
            }
        }

Basically, it uses reflection to get all the properties of the base and assign the values of this, to all the values that exist in A.

EDIT: To all you naysayers out there, I quickly tested this now with a base class that had 100 integer variables. I then had this assign method in a subclass. It took 46 milliseconds to run. I don't know about you, but I'm totally fine with that.

Solution 3

While there are many excellent answers here, I think the proper way to do this is by chaining the constructors:

public class A
{
    public string field1;
    public string field2;

    public A(string field1, string2 field2)
    {
         this.field1 = field1;
         this.field2 = field2;
    }
}

public class B : A
{
    public string field3;

    public B(string field1, string2 field2, string field3)
        : base(field1, field2)
    {
        this.field3 = field3;
    }
}

Solution 4

No, the syntax you are trying is not possible. In C# .NET you need to do:

public void Assign(A source) {
    field1 = source.field1;
    field2 = source.field2; 
}

Solution 5

Is the intent that these fields will be initialized once during object construction, or could "Assign" be called multiple times during an object's lifetime? If the latter, you can disregard the rest of this :)

Andrew's distinction between IS-A and HAS-A is an important one; if the relationship really is a HAS-A, his composition solution is the way to go.

If an IS-A relationship makes more sense (and you are able to modify A), a copy constructor might be a good idea:

public class A
{
    public string field1;
    public string field2;

    public A(A copyFrom)
    {
        this.field1 = copyFrom.field1;
        this.field2 = copyFrom.field2;
    }
}

public class B : A
{
    public string field3;

    public B(A source)
        : base(source)
    {
    }
}

You end up having to copy each of A's properties, but the responsibility for doing so resides in A where it belongs.

Share:
16,752
n99
Author by

n99

I tinker... I enjoy coding too I guess.

Updated on July 21, 2022

Comments

  • n99
    n99 almost 2 years

    How do I go about if I need to initialize an object's base with existing object? For example, in this scenario:

    public class A
    {
        public string field1;
        public string field2;
    }
    
    public class B : A
    {
        public string field3;
        public void Assign(A source)
        {
            this.base = source; // <-- will not work, what can I do here?
        }
    }
    

    Assign() method can, obviously assign values to the base class field-by-field, but isn't there a better solution? Since class B inherits from A, there must be a way to just assign A to the B.base

    In C++ this would be a trivial thing to do, but I can't seem to grasp how to do this in .NET

  • Jerph
    Jerph over 15 years
    this may technically work, but this is ugly and would slow down the init of the object.
  • BFree
    BFree over 15 years
    I hate when people say reflection is slow. Unless if you're dealing with performance critical code, it's really a non issue. I've done reflection that reflected over many many classes and all of their properties (over an entire DataContext class with 100 tables) and it took no time at all.
  • Dan Blair
    Dan Blair over 15 years
    +1 this does smell of inheritance being used for composition.
  • Jerph
    Jerph over 15 years
    I don't think OO is a bad design pattern, and you example makes OO totally useless.
  • Juliet
    Juliet over 15 years
    @Nick: there are plenty of occasions when composition solves problems that inheritance can't. The classic textbook example is when you need to hotswap implementation in one class with another, which is exactly what the author wants to do. (continued...)
  • Juliet
    Juliet over 15 years
    (from previous) Since the base class is a reference to the object instance, and not just a fancy container, its not possible to swap one base for another. Therefore, the only reasonable solution to the authors problem is to wrap the "base" in a property. Why do you think my approach is wrong?
  • Sam
    Sam over 15 years
    puke! better to advise the individual to not do things like that, or use composition, than to show them how to abuse reflection...
  • n99
    n99 over 15 years
    I hate to say it, but it looks like this method is the only one I could use :(
  • Robert P
    Robert P over 15 years
    This is a way, way roundabouts way of doing it. I'd highly recommend using constructors to set these fields. If a variable is private to a class, it's that way for a reason. If you have a parent class that you want children to manipulate, make the members protected or public.
  • n99
    n99 about 15 years
    I do understand that reflection is not made for that kind of access; I also understand that we were given tools and APIs in order to use them, therefore your solution seems fine. I'm not marking it as an answer, since it's not what I was asking about, but I approve of responsible use of this method
  • Johnny5
    Johnny5 almost 13 years
    I guess that's about what MemberwiseClone does. It maybe quite usefull, but I'm not a big fan of reflection neither.
  • usr4896260
    usr4896260 about 7 years
    I had a class with 20+ members and this saved me a lot of time and code. Wasn't slow at all. Great solution!
  • Peter Mortensen
    Peter Mortensen about 4 years
    But reflection is really, really slow and can result in quadratic behaviour (that is, it doesn't scale). I had an application that took minutes to serialise its data (directly affecting the users that used it for their daily work - that had to wait). Avoiding the implicit use of reflection (supported by a serialisation library) sped it up by a factor of 40, bringing the save time down to a few seconds.
  • Peter Mortensen
    Peter Mortensen about 4 years
    How does this answer the question? Why is serialisation relevant?