新編輯內容(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);
});
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 }
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 }
就上面這個問題,查詢了大量的資料,都沒有找到原因,誰能解答一下呢?