2017-09-08 53 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的答案太寬泛了。