OK!首先不得不說,筆者最開始認為interface是引用類型,為什么呢,那是因為經常看見IList list=...、ICollection list=...這一類的可以拿去指向實現的類的對象或者對象集合,前一段時間看過一篇也是關於討論interface時值類型還是引用類型的,結果好像說是引用類型,但是看着挺有道理的,最近有空自己試驗的一把,得出的結果讓我迷惑了,不知道是我錯了還是。。。
再來說說,接口不僅可以被值類型的如struct繼承,而且可以被class繼承,這兒就感覺看到interface不太像是引用類型了,再次就是它是不是值類型的呢,直接代碼演示
public interface IPlay { void PlayMessage(); } public struct ValueStudent : IPlay { #region IPlay 成員 public void PlayMessage() { Console.WriteLine("Hello,我是值類型!"); } #endregion } public class RefStudent : IPlay { #region IPlay 成員 public void PlayMessage() { Console.WriteLine("Hello,我是引用類型!"); } #endregion } class Program { static void Main(string[] args) { IPlay valuePlay = new ValueStudent(); valuePlay.PlayMessage(); Console.WriteLine("------------------------"); IPlay refStudent = new RefStudent(); refStudent.PlayMessage(); Console.ReadLine(); } }
結果就是:
Hello,我是值類型!
------------------------
Hello,我是引用類型!
再回到代碼,你看看
IPlay valuePlay = new ValueStudent();
IPlay refStudent = new RefStudent();
這兩句是重點啊,IPlay 他既可以指向值類型的也可以指向引用類型的,那它還是值類型的么?明顯它不是值類型了,那它到底是什么類型呢?今天突然想到3.5的.NET framework里面的var關鍵字,我勒個去啊var不就是既可以當爹又可以當媽的高富帥么,自此我的結論就是interface就和var一樣既可以指向值類型也可以指向引用類型,反正C#有個推斷類型的功能。
另外:VS2005不知道是哪個版本的.NET framework里面interface你愛怎么用就怎么用,但是沒有var關鍵字,我猜想后來的var是不是就復用interface的一些實現的功能。。。
歡迎各種表達。
好吧,我承認上面都是忽悠人的,其實我知道interface是引用類型,為什么,看IL代碼就知道了
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // 程式碼大小 54 (0x36) .maxstack 1 .locals init ([0] class ModelApp.IPlay valuePlay, [1] class ModelApp.IPlay refStudent, [2] valuetype ModelApp.ValueStudent CS$0$0000) IL_0000: nop IL_0001: ldloca.s CS$0$0000 IL_0003: initobj ModelApp.ValueStudent//初始化ValueStudent IL_0009: ldloc.2 IL_000a: box ModelApp.ValueStudent//valuePlay引用 裝箱ValueStudent實例 IL_000f: stloc.0 IL_0010: ldloc.0 IL_0011: callvirt instance void ModelApp.IPlay::PlayMessage() IL_0016: nop IL_0017: ldstr "------------------------" IL_001c: call void [mscorlib]System.Console::WriteLine(string) IL_0021: nop IL_0022: newobj instance void ModelApp.RefStudent::.ctor() IL_0027: stloc.1 IL_0028: ldloc.1 IL_0029: callvirt instance void ModelApp.IPlay::PlayMessage() IL_002e: nop IL_002f: call string [mscorlib]System.Console::ReadLine() IL_0034: pop IL_0035: ret } // end of method Program::Main
寫了這么多就是想弄明白一點為什么struct可以繼承interface並實現它的方法,而struct是值類型。。。
