亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當前位置:首頁 > IT技術 > Windows編程 > 正文

              dotnet C# 多次對一個對象調用構造函數(shù)會發(fā)生什么
              2021-09-10 18:23:17

              今天來玩一點變態(tài)的,使用反射獲取到某個類型的構造函數(shù),接著多次對此類型的某個對象調用構造函數(shù)方法。請問此時會發(fā)生什么

              假定有一個類型 Foo 的定義如下

                      class Foo : IDisposable
                      {
                          public Foo()
                          {
                          }
              
                          public int F1 { set; get; }
                          public int F2 { set; get; } = 10;
                      }

              先使用 RuntimeHelpers 的 GetUninitializedObject 方法創(chuàng)建對象而不調用構造函數(shù)

                      var foo = (Foo) RuntimeHelpers.GetUninitializedObject(typeof(Foo));

              如果給 Foo 的構造函數(shù)添加斷點,那么在運行上面代碼的時候,可以看到斷點是不會進入。詳細請看 dotnet C# 只創(chuàng)建對象不調用構造函數(shù)方法

              此時雖然 Foo 對象 foo 創(chuàng)建了,但是此對象還沒有經(jīng)過構造函數(shù)。接下來咱給此對象賦值,請看代碼

                              var foo = (Foo)RuntimeHelpers.GetUninitializedObject(typeof(Foo));
                              foo.F1 = 2;
                              foo.F2 = 2;

              請問此時的 Foo 里面的 F1 和 F2 屬性分別是什么?當然就是 2 了

              那如果用反射取出構造函數(shù),對 foo 對象調用構造函數(shù)呢

                              var constructorInfo = typeof(Foo).GetConstructor(new Type[0]);
                              constructorInfo!.Invoke(foo, null);

              此時可以看到 foo 對象里面,兩個屬性的值不同。具體是啥?自己去本文末尾拉代碼跑跑看

              接著再給 foo 對象賦值,如下面代碼

                              foo.F1 = 5;
                              foo.F2 = 5;

              然后再次調用構造函數(shù),如下面代碼

                              foo.F1 = 5;
                              foo.F2 = 5;
                              constructorInfo!.Invoke(foo, null);

              請問此時的 F1 和 F2 屬性的值是什么?

              回顧一下基礎知識,在類里面寫的 public int F2 { set; get; } = 10; 代碼其實是 C# 語言帶來的功能,在構建的時候,會被轉寫為大概如下的構造函數(shù)代碼

                          public Foo()
                          {
                              F2 = 10;
                          }

              通過 IL 代碼可以看到實際的邏輯如下

                  .method public hidebysig specialname rtspecialname instance void
                    .ctor() cil managed
                  {
                    .maxstack 8
              
                    // [53 43 - 53 45]
                    IL_0000: ldarg.0      // this
                    IL_0001: ldc.i4.s     10 // 0x0a
                    IL_0003: stfld        int32 KicheyurcherNiwhiyuhawnelkeera.Program/Foo::'<F2>k__BackingField'
              
                    // [48 13 - 48 25]
                    IL_0008: ldarg.0      // this
                    IL_0009: call         instance void [System.Runtime]System.Object::.ctor()
                    IL_000e: nop
              
                    // [49 13 - 49 14]
                    IL_000f: nop
              
                    // [50 13 - 50 14]
                    IL_0010: ret
              
                  } // end of method Foo::.ctor
              

              在 C# 中,其實構造函數(shù)也是一個函數(shù)而已,如上面代碼,只有寫給 F2 賦值的邏輯,而沒有給 F1 賦值的邏輯。因此在調用構造函數(shù)的時候,只會改變 F2 屬性的值,而不會更改 F1 屬性的任何值。也因為構造函數(shù)只是一個函數(shù),因此調用多次就和調用一個方法多次是一樣的

              本文所有代碼放在githubgitee 歡迎訪問

              可以通過如下方式獲取本文的源代碼,先創(chuàng)建一個空文件夾,接著使用命令行 cd 命令進入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

              git init
              git remote add origin https://gitee.com/lindexi/lindexi_gd.git
              git pull origin 5eb2ea112f2861791fafda9ed326657fd05572dd
              

              以上使用的是 gitee 的源,如果 gitee 不能訪問,請?zhí)鎿Q為 github 的源

              git remote remove origin
              git remote add origin https://github.com/lindexi/lindexi_gd.git
              

              獲取代碼之后,進入 KicheyurcherNiwhiyuhawnelkeera 文件夾

              ?

              dotnet C# 多次對一個對象調用構造函數(shù)會發(fā)生什么_git
              本作品采用知識共享署名-非商業(yè)性使用-相同方式共享 4.0 國際許可協(xié)議進行許可。歡迎轉載、使用、重新發(fā)布,但務必保留文章署名林德熙(包含鏈接:不得用于商業(yè)目的,基于本文修改后的作品務必以相同的許可發(fā)布。如有任何疑問,請與我

              本文摘自 :https://blog.51cto.com/u

              開通會員,享受整站包年服務立即開通 >