2017-09-08 52 views
0
 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如何得到正确的值,因为它是从Iregister铸造不具有LastName财产? 值“Shekar”如何从student.LastName传递到newstudent.LastNamex是否存储在它之间的某个地方?如果我想念一些基本知识,请原谅我。上传如何保留派生类的属性?

回答

3

您创建一个单独的对象,并在变量student中为其分配引用。

然后,您创建第二个参考到同一个对象,并将其分配给xxstudent指的是同一个对象,但x变量的类型表示只有在IRegister上定义的成员可用。

然后,您创建对同一对象的第三个引用并将其分配给newstudent。由于newstudentStudent类型,因此您可以从该参考中访问Student的所有成员。

不是变量只是存储引用。这是存储其自己的实际数据的对象,并且该对象在整个过程中保持不变。

3

我不知道newstudent.LastName如何获得正确的值,因为它是从没有LastName属性的Iregister中转出的 ?

事实是,x是一种Iregister但它指向Student对象,因此一旦铸造你能够访问Student领域。

1

当直接使用x,编译器允许您选择只在IRegister类型定义的成员,因为x是那种类型的。一旦您将x转换为Student,编译器允许您使用Student的任何成员,因为newstudent变量的类型为Student

+0

值“Shekar”如何从'student.LastName'传递给'newstudent.LastName'。 'x'是否存储在中间的某处? –

+0

'x'只是一个变量。整个过程只有一个对象在内存中。一个变量只指向那个对象。 – Kapol

+1

@NithinChandran:想象一下,如果我把蒙娜丽莎放进一个安全储物柜,我给三个不同的人一个钥匙给储物柜。三个人(变量)可以**访问储物柜,并可以在他们想要的时候查看蒙娜丽莎(物体),但**只有一个蒙娜丽莎绘画(物体)存在**。你的变量都有一个引用(locker key),但是它们的所有引用都指向内存中的同一个对象(它们的所有键都用于同一个locker) – Flater

1

接口店如何继承类的属性

接口不值。它们只确保实现接口的类中的某些属性和方法的可用性。

我不知道newstudent.LastName如何得到正确的值,因为它是从Iregister铸造不具有LastName财产?

溯造型对象不改变对象的类型,它只是改变了你使用的变量的类型。

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#互动窗口,测试了以下命令:

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,因为这是对象是什么。

这是因为类固有地是参考类型。对于值类型(例如floatint),这确实有不同的工作,但这与值和参考类型之间的固有差异有关。
如果你想知道为什么,在the difference between value and reference types in C#


读了如果你仔细想想,你的假设是没有意义的。在我的代码示例中,我有三个单独的变量:derived,derivedAsInterface,derivedAsBaseType。这些全部指向内存中的相同的对象。

这在逻辑上意味着同一个对象必须与所有三个变量兼容,否则当你想要使用这些变量时是不可能的。

  • 如果该对象已变成IMyInterface类型的对象,那么我的变量derivedAsBaseTypederived正确将不再起作用。
  • 如果对象更改为类型为BaseType的对象,则我的变量derived将不再正常工作。
  • 剩下的唯一的解释是,我的目标一直保持着其原有的类型(DerivedType),因为这是它如何能够保持与所有三个变量的兼容性的唯一途径。

如果你不明白他们为什么在内存中引用同一个对象,你应该阅读the difference between value and reference types in C#。本主题对于StackOverflow的答案太宽泛了。