Upcasting 如何保留派生的 类 的属性?
How Upcasting preserve derived classes's Properties?
static void Main(string[] args)
{
Student student = new Student()
{
ID = 12,
Name = "Manu",
LastName = "Shekar"
};
Iregister x = student;
Student newstudent = x as Student;
//Console.WriteLine(x.LastName); //Uncommenting this shows compilation error
Console.WriteLine(newstudent.LastName); //This Show "Shekar"
Console.ReadKey();
}
class Student : Iregister
{
public int ID { get; set; }
public string Name { get; set; }
public String LastName { get; set; }
}
interface Iregister
{
int ID { get; set; }
String Name { get; set; }
}
我想知道 newstudent.LastName
是如何从没有 LastName
属性 的 Iregister
中转换而来的正确值?
值 "Shekar" 如何从 student.LastName
传递到 newstudent.LastName
。 x
是否将其存储在两者之间?如果我错过了一些基础知识,请原谅我。
I wonder how the newstudent.LastName gets the correct value since it
is casted from Iregister which doesn't have LastName property?
事实是 x
是一个类型 Iregister
但它 指向 一个 Student
对象因此一旦转换你就可以访问 Student
字段。
当直接使用x
时,编译器只允许你选择定义在IRegister
类型上的成员,因为x
就是那个类型。将 x
转换为 Student
后,编译器允许您使用 Student
的任何成员,因为 newstudent
变量的类型为 Student
.
您创建了一个 对象 ,并在变量 student
中分配了对它的引用。
然后您为同一对象创建第二个 引用,并将其分配给 x
。 x
和 student
都引用同一个对象,但是 x
变量的类型意味着只有在 IRegister
上定义的成员可用。
然后您创建对同一对象的第三个引用并将其分配给 newstudent
。由于 newstudent
是 Student
类型,您可以从该引用访问 Student
的所有成员。
并不是说变量只是存储引用。是对象存储了它自己的实际数据,并且那个对象在整个过程中保持不变。
How Interface stores inherited class's Property
接口不存储值。它们仅确保实现接口的 类 中某些属性和方法的可用性。
I wonder how the newstudent.LastName
gets the correct value since it is casted from Iregister
which doesn't have LastName
property?
向下转换对象不会更改对象的类型,只会更改您正在使用的变量的类型。
public interface IMyInterface
{
String Name { get; }
}
public class BaseType : IMyInterface
{
public virtual String Name
{
get { return "Base Name"; }
}
}
public class DerivedType : BaseType
{
public override String Name
{
get { return "Derived Name"; }
}
}
然后我在 C# Interactive window 中测试了以下命令:
var derived = new DerivedType();
IMyInterface derivedAsInterface = derived;
BaseType derivedAsBaseType = derived;
derived.Name //returns "Derived Name"
derivedAsInterface.Name //returns "Derived Name"
derivedAsBaseType.Name //returns "Derived Name"
如您所见,每当您请求 Name
属性 时,该对象的行为仍然与 DerivedType
相同,因为这就是该对象。
这是因为 类 本质上是 引用类型 。对于 值类型 (例如 float
和 int
),这确实有所不同,但这与值类型和引用类型之间的内在差异有关。
如果您想知道原因,请继续阅读 the difference between value and reference types in C#
仔细想想,你的假设是不合理的。在我的代码示例中,我有三个独立的变量:derived
、derivedAsInterface
、derivedAsBaseType
。这些都指向内存中的同一个对象。
这在逻辑上意味着同一个对象必须兼容所有三个变量,否则无法在需要时使用所有这些变量。
- 如果将对象更改为
IMyInterface
类型的对象,那么我的变量 derivedAsBaseType
和 derived
将不再正常运行。
- 如果将对象更改为
BaseType
类型的对象,那么我的变量 derived
将不再正常运行。
- 唯一剩下的解释是我的对象始终保持其原始类型 (
DerivedType
),因为这是保持与所有三个变量兼容的唯一方式。
如果您不明白为什么它们在内存中引用同一个对象,您应该继续阅读 the difference between value and reference types in C#。这个主题太宽泛了,无法在 Whosebug 上找到答案。
static void Main(string[] args)
{
Student student = new Student()
{
ID = 12,
Name = "Manu",
LastName = "Shekar"
};
Iregister x = student;
Student newstudent = x as Student;
//Console.WriteLine(x.LastName); //Uncommenting this shows compilation error
Console.WriteLine(newstudent.LastName); //This Show "Shekar"
Console.ReadKey();
}
class Student : Iregister
{
public int ID { get; set; }
public string Name { get; set; }
public String LastName { get; set; }
}
interface Iregister
{
int ID { get; set; }
String Name { get; set; }
}
我想知道 newstudent.LastName
是如何从没有 LastName
属性 的 Iregister
中转换而来的正确值?
值 "Shekar" 如何从 student.LastName
传递到 newstudent.LastName
。 x
是否将其存储在两者之间?如果我错过了一些基础知识,请原谅我。
I wonder how the newstudent.LastName gets the correct value since it is casted from Iregister which doesn't have LastName property?
事实是 x
是一个类型 Iregister
但它 指向 一个 Student
对象因此一旦转换你就可以访问 Student
字段。
当直接使用x
时,编译器只允许你选择定义在IRegister
类型上的成员,因为x
就是那个类型。将 x
转换为 Student
后,编译器允许您使用 Student
的任何成员,因为 newstudent
变量的类型为 Student
.
您创建了一个 对象 ,并在变量 student
中分配了对它的引用。
然后您为同一对象创建第二个 引用,并将其分配给 x
。 x
和 student
都引用同一个对象,但是 x
变量的类型意味着只有在 IRegister
上定义的成员可用。
然后您创建对同一对象的第三个引用并将其分配给 newstudent
。由于 newstudent
是 Student
类型,您可以从该引用访问 Student
的所有成员。
并不是说变量只是存储引用。是对象存储了它自己的实际数据,并且那个对象在整个过程中保持不变。
How Interface stores inherited class's Property
接口不存储值。它们仅确保实现接口的 类 中某些属性和方法的可用性。
I wonder how the
newstudent.LastName
gets the correct value since it is casted fromIregister
which doesn't haveLastName
property?
向下转换对象不会更改对象的类型,只会更改您正在使用的变量的类型。
public interface IMyInterface
{
String Name { get; }
}
public class BaseType : IMyInterface
{
public virtual String Name
{
get { return "Base Name"; }
}
}
public class DerivedType : BaseType
{
public override String Name
{
get { return "Derived Name"; }
}
}
然后我在 C# Interactive window 中测试了以下命令:
var derived = new DerivedType();
IMyInterface derivedAsInterface = derived;
BaseType derivedAsBaseType = derived;
derived.Name //returns "Derived Name"
derivedAsInterface.Name //returns "Derived Name"
derivedAsBaseType.Name //returns "Derived Name"
如您所见,每当您请求 Name
属性 时,该对象的行为仍然与 DerivedType
相同,因为这就是该对象。
这是因为 类 本质上是 引用类型 。对于 值类型 (例如 float
和 int
),这确实有所不同,但这与值类型和引用类型之间的内在差异有关。
如果您想知道原因,请继续阅读 the difference between value and reference types in C#
仔细想想,你的假设是不合理的。在我的代码示例中,我有三个独立的变量:derived
、derivedAsInterface
、derivedAsBaseType
。这些都指向内存中的同一个对象。
这在逻辑上意味着同一个对象必须兼容所有三个变量,否则无法在需要时使用所有这些变量。
- 如果将对象更改为
IMyInterface
类型的对象,那么我的变量derivedAsBaseType
和derived
将不再正常运行。 - 如果将对象更改为
BaseType
类型的对象,那么我的变量derived
将不再正常运行。 - 唯一剩下的解释是我的对象始终保持其原始类型 (
DerivedType
),因为这是保持与所有三个变量兼容的唯一方式。
如果您不明白为什么它们在内存中引用同一个对象,您应该继续阅读 the difference between value and reference types in C#。这个主题太宽泛了,无法在 Whosebug 上找到答案。