我有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” - 不为空
这个例子是正确的。唯一的问题是我不知道Derived类是Class2还是class3或class4 ....我需要通用代码
答案 0 :(得分:2)
你不能(更重要的是,你不应该)这样做。当你在基类的构造函数中时,子类部分还没有被初始化,所以没有办法到达子类的成员:很简单,它们还不存在。
另一个问题是,Name2
属性可能根本不存在于子类中,即使在定义的级别:我可以从Class3
派生Class1
,然后给它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;
}
}
答案 1 :(得分: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
答案 2 :(得分:0)
我认为你不能因为当你实例化派生类时,首先调用基类构造函数来初始化基类,然后初始化派生类。在基类构造函数中,没有办法访问派生类成员,因为它们是当时不可用。
答案 3 :(得分:0)
由于Class2
的每个实例都具有Name2
属性。但对Class1
的对象实例无法保证同样的效果。
答案 4 :(得分: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
参数。然后派生类在它们“链接”它们的基类构造函数时必须提供该name参数。