C# 是否可以从指向子类对象的父类类型引用变量访问不在父类中的子类成员?

C# 是否可以从指向子类对象的父类类型引用变量访问不在父类中的子类成员?,c#,asp.net,.net,oop,inheritance,C#,Asp.net,.net,Oop,Inheritance,根据我的理解,如果我有一个指向子类对象的父类类型引用变量: ParentClass obj= new ChildClass(); obj.OnlyMembersThatHavebeenDerivedFromParentAreAvailable// am i wrong? 在下面的示例中,我从 我应该无法访问年度日历 派生类: public class FullTimeEmployee : Employee { public int AnnualSalary { g

根据我的理解,如果我有一个指向子类对象的父类类型引用变量:

ParentClass obj= new ChildClass();

obj.OnlyMembersThatHavebeenDerivedFromParentAreAvailable// am i wrong? 
在下面的示例中,我从 我应该无法访问年度日历

派生类:

 public class FullTimeEmployee : Employee
    {
        public int AnnualSalary { get; set; }
    }
public class PartTimeEmployee : Employee
    {
        public int HourlyPay { get; set; }
        public int HoursWorked { get; set; }
    }
Employee employee = null;
 employee = new FullTimeEmployee
                        {
                            Id = Convert.ToInt32(reader["Id"]),
                            Name = reader["Name"].ToString(),
                            Gender = reader["Gender"].ToString(),
                            DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]),
                            Type = EmployeeType.FullTimeEmployee,
                            AnnualSalary = Convert.ToInt32(reader["AnnualSalary"]) // how is AnnualSalary available here? 
                        };
派生类:

 public class FullTimeEmployee : Employee
    {
        public int AnnualSalary { get; set; }
    }
public class PartTimeEmployee : Employee
    {
        public int HourlyPay { get; set; }
        public int HoursWorked { get; set; }
    }
Employee employee = null;
 employee = new FullTimeEmployee
                        {
                            Id = Convert.ToInt32(reader["Id"]),
                            Name = reader["Name"].ToString(),
                            Gender = reader["Gender"].ToString(),
                            DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]),
                            Type = EmployeeType.FullTimeEmployee,
                            AnnualSalary = Convert.ToInt32(reader["AnnualSalary"]) // how is AnnualSalary available here? 
                        };
父类

 public class Employee
    {
        private int _id;
        private string _name;
        private string _gender;
        private DateTime _dateOfBirth;

        [DataMember(Order = 1)]
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        [DataMember(Order = 2)]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        [DataMember(Order = 3)]
        public string Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }

        [DataMember(Order = 4)]
        public DateTime DateOfBirth
        {
            get { return _dateOfBirth; }
            set { _dateOfBirth = value; }
        }

        [DataMember(Order = 5)]
        public EmployeeType Type { get; set; }
    }
以下代码如何有效

 public class FullTimeEmployee : Employee
    {
        public int AnnualSalary { get; set; }
    }
public class PartTimeEmployee : Employee
    {
        public int HourlyPay { get; set; }
        public int HoursWorked { get; set; }
    }
Employee employee = null;
 employee = new FullTimeEmployee
                        {
                            Id = Convert.ToInt32(reader["Id"]),
                            Name = reader["Name"].ToString(),
                            Gender = reader["Gender"].ToString(),
                            DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]),
                            Type = EmployeeType.FullTimeEmployee,
                            AnnualSalary = Convert.ToInt32(reader["AnnualSalary"]) // how is AnnualSalary available here? 
                        };

你是对的,你不能写:

employee.AnnualSalary = 1234;
但这不是你的情况。
您只是使用对象初始值设定项来初始化
FullTimeEmployee
对象(您可以访问所有公共字段/属性)。
基本上,您正在执行以下操作:

FullTimeEmployee employeeTemp = new FullTimeEmployee();
employeeTemp .AnnualSalary =2000;
Employee employee =employeeTemp;
更新 我认为不能将父类对象类型转换为子类 对象,因为子对象可以做父对象可以做的任何事情,反之亦然 事实并非如此

再一次,你是对的。
再一次,这不是你的情况…
方法的返回类型可能是Employee,但实际返回的对象可能是其他对象(派生类)。
在这种情况下,您可以安全地将对象强制转换为派生类型。
检查以下示例

namespace CastExample
{
  class Program
  {
    static void Main(string[] args)
    {
        Employee emp = GetEmployee();
        FullTimeEmployee full = (FullTimeEmployee)emp;
        System.Console.WriteLine(full.AnnualSalary);
        PartTimeEmployee part = (PartTimeEmployee)emp;//InvalidCastException
        System.Console.ReadLine();
    }

    static Employee GetEmployee()
    {
        return new FullTimeEmployee() { Name = "George", AnnualSalary = 1234   };
    }
  }
  public class Employee
  {
     public string Name;
  }
  public class FullTimeEmployee : Employee
  {
     public int AnnualSalary { get; set; }
  }
  public class PartTimeEmployee : Employee
  {
      public int HourlyPay { get; set; }
      public int HoursWorked { get; set; }
  }
}
他也可以访问私人财产

是的,您可以使用反射访问私有字段


选中此项:
@Marc Gravell的回答解释了为什么你可以这样做,但要特别注意@Tamas Czinege的回答(我在这里再次引用)

成员可访问性不是安全功能。它是用来保护的 程序员反对他自己。它有助于实施 封装,但它决不是一个安全特性


你有什么问题吗?它编译吗?我没有在visual studio中重新创建它。我看了同一个博客的视频教程(使用了和那个博客上完全相同的代码),他成功地编译并运行了它。所以,是的,它确实可以编译。但是为什么呢?哦!我现在明白了。该死的初始化语法!顺便说一句,以确保我的方法是否返回此
employee
对象。打电话的人无法访问年度日历,对吗?在这种特定情况下,将值赋给AnnualSalary将是徒劳的,对吗?@Arbaaz如果您的方法返回Employee类型的对象,则调用方无法使用访问AnnualSalary。表示法。**但**调用方可以将对象强制转换为FullTimeEmployee,然后访问FullTimeEmployee类的所有公共属性,包括AnnualSalary。(他也可以非常轻松地访问私有属性…)您确定吗?我的意思是,我认为不能将父类对象类型转换为子类对象,因为子类可以做父类可以做的一切,但反之亦然。他也可以访问私人财产??怎么用?很抱歉,这有点脱离上下文,但我需要知道如何操作。@Arbaaz,请查看我的更新答案。如果您有更多问题,请关闭此问题并询问新问题。谢谢,我真的不知道可以通过这种方式访问私有字段。