[英]Why an object saves properties when upcasted
关于c#中的upcast,我有一个简单的问题。 例如,我有两个接口:
interface IUSer
{
string UserName { get; set; }
}
interface IAdmin: IUSer
{
string Password { get; set; }
}
...以及实现IAdmin接口的类:
class Admin : IAdmin
{
public string Password { get; set; }
public string UserName { get; set; }
}
当我创建一个Admin类型的对象并尝试将其向上转换为IUser时,从技术上讲,我只能访问UserName user.UserName:
var admin = new Admin() { UserName = "Arthur", Password = "hello" };
var user = (IUSer)admin;
Console.WriteLine( user.UserName );
...但是如果我使用Reflection循环遍历此对象的属性,就像这样:
private static void Outputter(IUSer user)
{
foreach (var prop in user.GetType().GetProperties())
{
Console.WriteLine(prop.Name + " " + prop.GetValue(admin));
}
}
...我也可以看到密码属性。 问题是 - 为何在升级时保存?
问题是 - 为何在升级时保存?
因为铸造根本不会改变对象 。 它只会改变您查看对象的方式。
把它想象成一个人。 您可能有不同的方式让人们可以看到您:
他们只“看到”你的某些方面,但这不会改变你的身份。
同样,简单的引用转换不会更改对象。 如果你调用user.GetType()
它仍然会报告对象的实际类型。 只是当您通过特定镜头(无论是界面还是基类)查看对象时,您只能看到镜头向您显示的成员。
(请注意,调用用户定义的转换的转换,例如从XElement
转换为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)}");
}
}
虽然我不确定在大多数情况下用反射来做这件事特别有用。
当你将任何类型的对象强制转换为它们的基类型时,你只需要保持那个对象类型为base的对象。
对象不会因此而忽略其属性。
如果您看到一个最简单的示例: 使用非泛型集合
当您在ArrayList
添加一些对象(比如Admin
类)时,您实际上是将该对象转换为类型object
(Boxing),然后将其存储为arraylist。 所以这是上传的最终例子! 怎么样?
对象类型是.NET Framework中Object的别名。 在C#的统一类型系统中,所有类型,预定义和用户定义的引用类型和值类型都直接或间接地从Object继承。
现在, object
类型不包含userName
password
等属性。 因此,当您尝试从arraylist直接获得的对象访问这些属性时,您将无法执行此操作。 因为当前您正在处理类型object
并且您只能访问object
类型支持的那些属性或成员(但是在这里您无法访问,但仍然存在这些属性)。 另外作为其他答案中的注释GetType()
方法也一定会返回它的原始类型。
但是,当您将该原始对象从阵列列表中返回到Admin
类型(取消装箱)时,您将看到这些属性在您的对象中,就像之前一样。 只有更改的是,现在您可以访问它们,因为Admin
类型支持它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.