我们说我们有两节课。第一个是人
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace People
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
第二个是老师
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace People
{
class Teacher:Person
{
public string Position { get; set; }
}
}
我想使用这种语法创建一个教师对象Person teacher = new Teacher();
当我创建它并尝试引用位置属性时,我无法...为什么会发生这种情况?我可以使用这种语法Person teacher = new Teacher() {Position="boss" };
,但即使如此,我也无法使用" teacher.Position"来指代教师职位。
答案 0 :(得分:3)
你可以这样做:
Person teacher = new Teacher() { Position="boss" };
var position = ((Teacher)teacher).Position;
答案 1 :(得分:2)
问题是由引用的类型引起的。在声明中
Person teacher = new Teacher() { Position="boss" };
右侧创建一个Teacher
类型的新对象,并初始化Position
属性。但是,引用teacher
的类型为Person
。虽然teacher
引用的对象实际上是Teacher
类型,但引用本身属于更一般的类型Person
。
非正式地说,在上面的声明中,您声明要将teacher
引用到Person
,无论它是否属于更多派生类型Teacher
,因此引用本身不知道它引用了更特殊的类型Teacher
,因此不知道有Position
属性。
从技术上讲,这是必要的,因为在运行时,可以让teacher
引用源自Person
的其他对象,比如Student
或Wizard
,也许也不会有Position
财产。
答案 2 :(得分:1)
这样做:
Teacher
您创建了teacher
类型的对象,但您的引用类型(Person
)的类型为Person
- 这意味着使用此引用只能访问{{1}类型的所有成员}}
要访问Teacher
成员,您应该创建Teacher
类型的引用:
Teacher teacher = new Teacher();
var position = teacher.Position;
或者您应该将您的引用转换为Teacher
类型:
Person teacher = new Teacher();
var position = ((Teacher)teacher).Position;
答案 3 :(得分:0)
原因是,编译器在将其分配给显式声明为基类型的变量后,根本不知道继承的类型。
原因是,虽然对象仍然是Teacher
的实例,但编译器只能确保此对象在运行时是Person
,因此它不允许您访问Teacher
类的任何属性。
将变量声明为var
将允许编译器根据分配给它的内容确定该变量的类型。
答案 4 :(得分:0)
阅读抽象工厂设计模式:) 这将回答你的问题。