-8

I have 2 classes:

public class Class1
{
   private string Name1;
   public Class1()
   {
      //How to get Name2 of the derived class?
   }  
}

public class Class2 : Class1
{
   private string Name2 = "asd"; 
   public Class2(){}
}

How to get Name2 of the derived class in the base constructor?

public class Class1
{
   private string Name1;
   public Class1()
   {
       class2 xxx = this as class2      
       if (class2 != null) 
          this.Name1 = xxx.Name2;
   }  
}

"this as class2" - is not null

This example is correct. The only thing is I don't know Derived class is Class2 or class3 or class4 .... I need universal code

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480

5 Answers5

2

You cannot (and more importantly, you should not) do that. When you are in the constructor of the base class, the subclass portion has not been initialized yet, so there is no way to get to the members of the subclass: quite simply, they do not exist yet.

Another problem is that the Name2 attribute may not be present in a subclass at all, even at the level fo the definition: I can derive Class3 from Class1, and give it Name3 attribute instead of Name2.

All this does not touch on such "insignificant" matters as breaking encapsulation: Name2 is a private member, which may be removed in the future implementations of the Class2.

The only way for the subclass to communicate things to superclass in a constructor is passing parameters. This would work:

public class Class1 {
    private string Name1;
    public Class1(string subclassName2)
    {
        // Subclass has passed its Name2 here
    }  
}

public class Class2: class1 {
    private string Name2; 
    public Class2(string myName) : base(myName) {
        Name2 = myName;
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • @Bobby It does not make a difference: when `Class2` is being constructed, the constructor of `Class1` is invoked first. Even if your little trick succeeded syntactically, all you'd get is `null` - always, regardless of the actual value of `Name2` in `Class2`. – Sergey Kalinichenko Mar 10 '13 at 13:55
  • i tested this and a have not null relult in "This as Class2" –  Mar 10 '13 at 14:00
  • @Bobby I mean it's `Name2` that is going to be `null`, not your `class2` variable. – Sergey Kalinichenko Mar 10 '13 at 14:28
  • Name2 is going to be not null if I assign name2 "asd" value –  Mar 10 '13 at 14:36
  • @Bobby No, it's not: try it. You keep missing the timing issue: you assign it in `Class2` *after* you access it in `Class1`. – Sergey Kalinichenko Mar 10 '13 at 14:48
  • before Class2 constructor All fields are assigned in Class2. Then class2 constructor go to Class1 constructor where Name2 is "asd" (for example). It works at my computer. –  Mar 10 '13 at 14:52
1

You can access the code in the derived class from the base class code, but only from within an object which is actually a derived class object, and then only if the methods involved are virtual methods.

If you have an object which is itself an instance of the base class, then from within that instance you cannot see derived class code from the base class .

example

public class Baseclass{

  public void Foo()
  {
      Bar();
  }
  public virtual void Bar()
  {
     print("I'm a BaseClass");}}


public classs Derived: BaseClass{

  public override void Bar()
  {
     print("I'm a Derived Class");}}


Main()

   var b = new BaseClass();
   x.Foo()  // prints "I'm a BaseClass" 
   // This Foo() calls Bar() in base class  
    var d = new Derived();
   d.Foo()  // prints "I'm a Derived Class" 
   // in above, the code for Foo() (in BaseClass)
   //  is accessing Bar() in derived class      
j.s.banger
  • 412
  • 1
  • 6
  • 15
0

I think you could not because when you instantiate derived class, base class constructor is called first to initialize base class and then the derived class is initialized.Within the base class constructor there is no way to access derived class members because they are not available at that time.

nsconnector
  • 838
  • 6
  • 12
0

You cannot do it. It strictly violates the Object Oriented Approach programming ground rules.

As each instance of Class2 will have the Name2 property. But the same cannot be guaranteed for instance of object for Class1.

Community
  • 1
  • 1
Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
0

It's not really clear what you're trying to achieve. It is possible to do the following, but I don't think it's good practice:

    interface IHasName2
    {
        string Name2 { get; }
    }
    class Class1
    {
        string Name1;

        public Class1()
        {
            var withName2 = this as IHasName2;
            if (withName2 != null)
            {
                Name1 = withName2.Name2;
            }
        }
    }

Then classes deriving from Class1 may implement IHasName2 if they like.

But maybe you want an abstract class to make sure derived classes specify a Name2. It could be like this:

    abstract class Class1
    {
        string Name1;

        // instance property required to be implemented by deriving classes
        protected abstract string Name2 { get; }

        // instance constructor
        protected Class1()
        {
            // 'Name2' can be read already here (dangerous?)
            Name1 = Name2;
        }
    }

Finally, consider the simple solution proposed by dasblinkenlight to have the instance constructors of Class1 take in a string parameter for the name. Deriving classes would then have to supply that name parameter when they "chain" their base class constructor.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181