为什么对象在上传时会保存属性

Art*_*kov 2 c# upcasting

关于c#中的upcast,我有一个简单的问题.例如,我有两个接口:

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

interface IAdmin: IUSer
{
    string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...以及实现IAdmin接口的类:

class Admin : IAdmin
{
    public string Password { get; set; }
    public string UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我创建一个Admin类型的对象并尝试将其向上转换为IUser时,从技术上讲,我只能访问UserName user.UserName:

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

...但是如果我使用Reflection循环遍历此对象的属性,就像这样:

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

...我也可以看到密码属性.问题是 - 为何在升级时保存?

Jon*_*eet 13

问题是 - 为何在升级时保存?

因为铸造根本不会改变对象.它只会改变您查看对象的方式.

把它想象成一个人.您可能有不同的方式让人们可以看到您:

  • 一个同事
  • 经理
  • 一位家庭成员
  • 一个朋友

他们只"看到"你的某些方面,但这不会改变你的身份.

同样,简单的引用转换不会更改对象.如果你调用user.GetType()它仍然会报告对象的实际类型.只是当您通过特定镜头(无论是界面还是基类)查看对象时,您只能看到镜头向您显示的成员.

(请注意,调用用户定义的转换(例如,从XElementto 转换)的转换string完全不同.它返回对新对象的引用,而不是仅以不同方式关注现有对象.)

如果您只想查看IUser属性,请使用typeof(IUser).GetProperties()而不是GetType()先调用:

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

虽然我不确定在大多数情况下用反射来做这件事特别有用.