让我说我有一个库1.0.0版,其中包含以下内容:
public class Class1 { public virtual void Test() { Console.WriteLine( "Library:Class1 - Test" ); Console.WriteLine( "" ); } } public class Class2 : Class1 { }
我在一个控制台应用程序中引用了这个库,内容如下:
class Program { static void Main( string[] args ) { var c3 = new Class3(); c3.Test(); Console.ReadKey(); } } public class Class3 : ClassLibrary1.Class2 { public override void Test() { Console.WriteLine("Console:Class3 - Test"); base.Test(); } }
Console:Class3 - Test Library:Class1 - Test
如果我构建一个新版本的2.0.0版本的库,如下所示:
public class Class1 { public virtual void Test() { Console.WriteLine( "Library:Class1 - Test V2" ); Console.WriteLine( "" ); } } public class Class2 : Class1 { public override void Test() { Console.WriteLine("Library:Class2 - Test V2"); base.Test(); } }
并将此版本复制到包含我的控制台程序的bin文件夹并运行它,结果是:
Console:Class3 - Test Library:Class1 - Test V2
即,Class2.Test方法永远不会执行,Class3.Test中的base.Test调用似乎绑定到Class1.Test,因为当编译控制台程序时,Class2.Test不存在.
这对我来说非常惊讶,并且在不重新编译应用程序的情况下部署新版本的库的情况下可能会是一个大问题.
还有其他人有这方面的经验吗?
有什么好的解决方案吗?
这使得它很容易添加空的覆盖,只是调用base,以防我以后在这个级别添加一些代码…
编辑:
似乎确定在编译时该调用必须绑定到第一个现有的基本方法.我想知道为什么.如果我使用我的库的版本2构建我的控制台程序(这应该意味着调用被编译为调用Class2.Test),然后将bin文件夹中的dll替换为版本1,结果如下所示:
Console:Class3 - Test Library:Class1 - Test
所以当Class2.Test不存在时,没有运行时错误.为什么基本调用不能被编译才能首先调用Class2.Test?
从Eric Lippert或与编译器合作的其他人获得评论将是有趣的
解决方法
这是3月29日我的博客的主题:
http://blogs.msdn.com/ericlippert/archive/2010/03/29/putting-a-base-in-the-middle.aspx
原来,C#1.0做到了这一点,而且这个决定会导致一些有趣的崩溃和性能问题.我们在C#2.0中改用了新的方式.
我从这个问题中学到很多东西.有关详细信息,请参阅博客.