Click here to Skip to main content
15,076,130 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. Im getting confused with this:
C#
using System;

namespace CSharp_Practicing
{
    class Program
    {
        static void Main()
        {
            Person p = new Student(); // Here in this line im getting confused. I am making a reference of type Person and making this reference point to the Student constructor right ? 
            p = p as Student; // In this line im doing a cast to Student but still cant access the ID property
            
        }
    }

    class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }

    class Student : Person
    {
        public int ID { get; set; }
    }
}


What I have tried:

Searching for information in the internet but can't find explaination for this.
Posted
Updated 29-Jun-17 11:41am

Person p = new Student();
Appears to be a type mismatch: a Person object cannot hold a Student object.

It cannot hold p.ID as a member as there's no place for it.

Consider if you have an object of type Point(), which is an integer pair (x, y) as members.
int q = new Point();  // makes no sense.  Does q hold x or y
   
Comments
Richard Deeming 29-Jun-17 16:48pm
   
"a Person object cannot hold a Student object"

Except that it can: Student inherits from Person, so it's perfectly valid to put a Student instance in a Person variable.
I think when you do:
C#
Person p = new Student();
you loose the ID, as p is now a Person class, so you should use:
C#
Student p = new Student();
   
Comments
Richard Deeming 29-Jun-17 16:50pm
   
Technically, you don't lose the ID; you just can't see it because the compile-time type of the variable doesn't have an ID property.

The run-time type of the variable is still Student, and the ID is still there. :)
You are trying to assign p, of type Person, as student even though its type is still Person which contains no Id property.

You need to declare your cast as Student to a new variable, say "student".

Ex:

C#
Person p = new Student();
        
        // still of type Person so cannot access Id since there is no Id on class Person
        p = p as Student;

        Student student = p as Student;
        var studentId = student.Id;
   
Comments
The_Unknown_Member 29-Jun-17 16:08pm
   
explain me this line of code:
Student student = p as Student; < -------------
David_Wimbley 29-Jun-17 19:43pm
   
So you have a class of student and person. Person is considered to be your base class and student is your child class that inherits from person.

Your problem is, I think, that you are confusing which is the parent/base class. You are trying to access a property from your child class (Student) from declaring your variable as your base class type (Person). If you wanted to access the name/age property from student, which are properties of the base class, you can do so, but you cannot reverse this process in that you cannot access properties of a child class from a base class.

The line you single out declares a variable of type Student, and you are casing your variable Person (p) as type Student
Person p = new Student();

Should be Student p = new Student(); This would instantiate an object of type Student which inherits the Person properties and implements the ID property.

p = p as Student; this typecast is not necessary.

now you can access the ID with p.ID
   
Comments
The_Unknown_Member 29-Jun-17 16:14pm
   
I know that. But Im learning the POLYMORPHISM
Person p;
declares a new variable with the compile-time type of Person.

It can hold any object of type Person, or of any type derived from Person. As a result, the compiler will only let you access the members defined on the Person type or its base types.

p = new Student();
creates a new instance of the Student class, and stores it in the p variable.

This works, because the Student class inherits from the Person class. A Student is a Person.

The variable now has a run-time type of Student. But the compile-time type is still Person.

The compiler won't let you access the ID property, because it's not defined on the Person class or one of its base classes. The compiler has no idea what the run-time type of the variable will be, and whether it will have an ID property.

p = p as Student;
takes the value stored in p, and attempts to cast it to a Student instance. If it succeeds, the value will be put back in the variable p. If it fails, the variable p will be set to null.

But the compile-time type of p does not change. You still cannot access the ID property, because the compiler has no idea whether it even exists.


There are various ways you can access the property:
Student s = p as Student;
int id = s == null ? 0 : s.ID;

int id = (p as Student)?.ID ?? 0; // Shorter version of the previous code.

int id = ((Student)p).ID; // Throws an exception if p is not a Student.

dynamic d = p;
int id = d.ID; // Throws an exception if p does not have a public readable
               // "ID" property that can be converted to an int.
               // Also much slower than the other options.
   
How do you want to use Polymorphism? For instance, you are already overloading the assignment operator to be able to set and get property values for the Person and Student objects with "=". If you also want to overload the assignment operator to allow you to do something like Person a = Student b then you would have to provide the logic for that yourself.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900