简体   繁体   中英

Why an object saves properties when upcasted

I've got a simple question concerning upcasting in c#. For example I have two interfaces:

interface IUSer
{
    string UserName { get; set; }
}

interface IAdmin: IUSer
{
    string Password { get; set; }
}

...and a class implementing IAdmin interface:

class Admin : IAdmin
{
    public string Password { get; set; }
    public string UserName { get; set; }
}

When I create an object of type Admin and try to upcast it to IUser, technically I can then only access UserName user.UserName:

var admin = new Admin() { UserName = "Arthur", Password = "hello" };
var user = (IUSer)admin;
Console.WriteLine( user.UserName );

...but If I cycle through this object's properties using Reflection, like that:

    private static void Outputter(IUSer user)
    {
        foreach (var prop in user.GetType().GetProperties())
        {
            Console.WriteLine(prop.Name +  " " + prop.GetValue(admin));
        }
    }

...I can also see Password property. The question is - why it is saved when upcasted?

The question is - why it is saved when upcasted?

Because casting doesn't change the object at all. It just changes how you're viewing the object.

Think of it like being a person. You may have different ways that people can view you:

  • A colleague
  • A manager
  • A family member
  • A friend

They only "see" certain aspects of you, but that doesn't change who you are.

Likewise a simple reference conversion doesn't change the object. If you call user.GetType() it will still report the actual type of the object. It's just that when you view the object through a particular lens (whether that's an interface or a base class) you only see the members that lens shows you.

(Note that a cast that calls a user-defined conversion, eg casting from XElement to string , is entirely different. That returns a reference to a new object, rather than just regarding the existing object in a different way.)

If you only want to see the IUser properties, use typeof(IUser).GetProperties() instead of calling GetType() first:

private static void Outputter(IUser user)
{
    foreach (var prop in typeof(IUser).GetProperties())
    {
        Console.WriteLine($"{prop.Name}: {prop.GetValue(user)}");
    }
}

Although I'm not sure it's particularly useful to do that with reflection in most cases.

when you cast the object of any type to their base type, you are just holding that object with they type of base.

object doesn't loos its properties by that.

If you see a simplest example : Use of non generic collection

when you add some object (let's say of Admin class) in ArrayList , you are actually converting that object into type object (Boxing) and then store it arraylist. So it is ultimate example of up-casting! How?

The object type is an alias for Object in the .NET Framework. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from Object.

Full Post

Now object type doesn't hold properties like userName password . So when you try to access those property from the object you get directly from arraylist, you will not able to do so. Because current you are dealing with the type object and you will get access only those properties or members which is supported by object type (but here you are not getting access, still those properties are there). In addition as note in other answer GetType() method will surely return it's original type too.

But when you get that original object back from array list by casting it back to Admin type (Unboxing) , you will see those properties are there in your object as they were before. Only thing which is changed is, now you are able to access them because Admin type supports them.

Read this for more detail

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM