关于带泛型约束的虚函数在托管函数中的调用问题 - Zachary.XiaoZhen

关于带泛型约束的虚函数在托管函数中的调用问题

新编辑内容(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 }

 

 

就上面这个问题,查询了大量的资料,都没有找到原因,谁能解答一下呢? 

 

你可能感兴趣的:(关于带泛型约束的虚函数在托管函数中的调用问题 - Zachary.XiaoZhen)