-8

我有 2 节课:

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(){}
}

如何Name2在基构造函数中获取派生类?

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

“this as class2” - 不为空

这个例子是正确的。唯一的事情是我不知道派生类是 Class2 或 class3 还是 class4 .... 我需要通用代码

4

5 回答 5

2

你不能(更重要的是,你不应该)那样做。当您在基类的构造函数中时,子类部分尚未初始化,因此无法获取子类的成员:很简单,它们还不存在。

另一个问题是Name2属性可能根本不存在于子类中,即使在定义级别:我可以从 派生Class3Class1并赋予它Name3属性而不是Name2

所有这些都没有涉及诸如破坏封装之类的“微不足道”的事情:Name2是一个私有成员,可能会在Class2.

子类在构造函数中与超类进行通信的唯一方法是传递参数。这会起作用:

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;
    }
}
于 2013-03-10T12:50:51.067 回答
1

您可以从基类代码访问派生类中的代码,但只能从实际上是派生类对象的对象内访问,并且仅当涉及的方法是虚拟方法时。

如果您有一个对象本身就是基类的实例,那么从该实例中您将看不到来自基类的派生类代码。

例子

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      
于 2013-03-10T13:13:27.247 回答
0

我认为你不能,因为当你实例化派生类时,首先调用基类构造函数来初始化基类,然后初始化派生类。在基类构造函数中,无法访问派生类成员,因为它们在那时。

于 2013-03-10T12:49:43.913 回答
0

目前还不清楚您要达到的目标。可以执行以下操作,但我认为这不是一个好习惯:

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

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

然后派生的类Class1可以根据需要实现IHasName2

但也许你想要一个abstract类来确保派生类指定一个Name2. 它可能是这样的:

    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;
        }
    }

最后,考虑 dasblinkenlight 提出的简单解决方案,让实例构造函数Class1接受string名称参数。然后,派生类在“链接”其基类构造函数时必须提供该名称参数。

于 2013-03-10T14:11:50.893 回答
0

你做不到。它严格违反了面向对象方法编程的基本规则。

因为每个实例都Class2将具有该Name2属性。但是对于对象的实例,不能保证相同Class1

于 2013-03-10T12:57:37.237 回答