【问题标题】:Is it possible to access child class members that are not in parent class from a parent class type reference variable pointing to child class object?是否可以从指向子类对象的父类类型引用变量访问不在父类中的子类成员?
【发布时间】:2016-03-26 17:19:36
【问题描述】:

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

ParentClass obj= new ChildClass();

obj.OnlyMembersThatHavebeenDerivedFromParentAreAvailable// am i wrong? 

在下面的示例中,我取自 click here 我应该无法访问年薪

派生类:

 public class FullTimeEmployee : Employee
    {
        public int AnnualSalary { get; set; }
    }

派生类:

public class PartTimeEmployee : Employee
    {
        public int HourlyPay { get; set; }
        public int HoursWorked { get; set; }
    }

父类

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

以下代码如何有效? :

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

【问题讨论】:

  • 你有问题吗?它编译了吗?
  • 我没有在 Visual Studio 中重新创建它。我正在观看来自同一博客的视频教程(使用该博客上完全相同的代码),他能够成功编译并运行它。所以是的,它确实可以编译。但是怎么会呢?

标签: c# asp.net .net oop inheritance


【解决方案1】:

你是对的,你不能写:

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

而且他也可以访问私有财产??

是的,您可以使用反射访问私有字段
Find a private field with Reflection?
How to get the value of private field in C#?
c# use reflection to get a private member variable from a derived class

检查这个: Why can reflection access protected/private member of class in C#?
@Marc Gravell 的回答解释了为什么你可以这样做,但要特别注意@Tamas Czinege 的回答(我在这里再次引用)

会员可访问性不是一项安全功能。它在那里保护 程序员反对他或她自己。它有助于实施 封装,但绝不是安全功能。

【讨论】:

  • 哦!我现在明白了。该死的初始化语法!顺便说一句,只是为了确定我的方法是否返回这个 employee 对象。来电者无法访问AnnualSalary吗?在这种特殊情况下,将值分配给 AnnualSalary 是徒劳的,对吧?
  • @Arbaaz 如果您的方法返回 Employee 类型的对象,则调用者无法使用 .符号。**但是**调用者可以将对象转换为 FullTimeEmployee,然后访问 FullTimeEmployee 类的所有公共属性,包括AnnualSalary。(他也可以很容易地访问私有属性......)
  • 你确定吗?我的意思是我认为不能将父类对象类型转换为子类对象,因为孩子可以做父母可以做的所有事情,但反之亦然是不正确的。他也可以访问私人财产??如何?很抱歉,它有点断章取义,但我需要知道怎么做。
  • @Arbaaz ,请参阅我的更新答案。如果您有更多问题,请关闭此问题并提出新问题
  • 谢谢 我真的不知道私有字段可以通过这种方式访问​​。
猜你喜欢
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多