關於帶泛型約束的虛函數在托管函數中的調用問題


新編輯內容(2012-10-10 14:49:00)

根據1樓朋友doylecnn的測試,我重新進行了嘗試,發現是VS2012才有這個問題,估計是個BUG,看來新東西不能亂用啊。

VS2010下正常,Mac里Mono下正常。跟操作系統沒有關系。

 

為啥VS2012會有這個問題呢?用的也是.NET 4沒有用.NET 4.5。只是編譯時一個采用VS2010一個采用VS2012,就有不同的結果?

我已經上傳了編譯程序和源代碼,感興趣的可以下載玩玩。。。。。。 

點擊下載


今天遇到個很奇怪的問題,我寫了一個組件,要求傳入一個Action對象,於是我同事調用時傳入了一個匿名函數,如下:

 

caller.Process(()=>{
     base.Delete<News>(id);
}); 

 

然后運行后出現異常:類型參數“TEntity”與類型參數“TEntity”的約束沖突。

那么多年第一次遇到這種稀有問題,經過跟蹤調試,發現這個問題出現的條件如下:

1.要調用的方法必須是一個在父類當中的虛方法(virtual)。

2.在子類中,必須通過一個托管函數來直接調用父類的base.Func()虛方法,如果子類進行了覆蓋(override),然后在覆蓋中使用base.Func()都沒有問題。

3.父類的這個虛方法是泛型 ,並且必須具備泛型約束,沒有約束也不會出現問題。

寫了個簡單的示例代碼:

 

 1  using System;
 2  using System.Collections.Generic;
 3  using System.Linq;
 4  using System.Text;
 5 
 6  namespace VirtualFunction
 7 {
 8      class Program
 9     {
10          static  void Main( string[] args)
11         {
12             SubClass sub =  new SubClass();
13             sub.CallFunc();
14             Console.ReadKey();
15         }
16     }
17 
18      public  abstract  class SuperClass
19     {
20          public  virtual  void Func<TEntity>()
21              where TEntity :  class
22         {
23             Console.WriteLine( " super class's function ");
24         }
25 
26          public  void NonVirtualFunc<TEntity>()
27              where TEntity :  class
28         {
29             Console.WriteLine( " super class's none virtual function ");
30         }
31     }
32 
33      public  class SubClass : SuperClass
34     {
35          public  delegate  void Caller();
36 
37          /// /這里覆蓋父類的虛方法,但是下面用不同的調用方式調用,實際測試結果為有沒有這個覆蓋方法效果都一樣,該異常的地方還是異常
38           public  override  void Func<TEntity>()
39         {
40              base.Func<TEntity>();
41         }
42 
43          public  void CallFunc()
44         {
45              // 這里采用普通方式調用父類的虛方法Func
46               base.Func< string>();
47 
48              // 這里使用一個代理來調用父類的虛方法Func,注意這里子類並沒有覆寫父類的Func方法
49              Action action =  new Action(() =>
50             {
51                  base.NonVirtualFunc< string>(); // 不會出現異常
52                   this.Func< string>(); // 不會出現異常
53                   base.Func< string>(); // 出現異常
54              });
55             action();
56 
57              // 另外一種托管調用方式,效果和上面通過Action調用一樣
58              Caller caller = () =>
59             {
60                  base.NonVirtualFunc< string>();
61                  base.Func< string>();
62             };
63             caller();
64         }
65     }
66 }

 

 

就上面這個問題,查詢了大量的資料,都沒有找到原因,誰能解答一下呢? 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM