方法绑定到外部库无法处理的新的虚拟方法&QUOT基方法...之间QUOT; [英] Method binding to base method in external library can't handle new virtual methods "between"

查看:90
本文介绍了方法绑定到外部库无法处理的新的虚拟方法&QUOT基方法...之间QUOT;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以说我有一个库,版本1.0.0,包含以下内容:

 公共类的Class1 
{
公共虚拟无效测试()
{
Console.WriteLine(图书馆:1级 - 测试);
Console.WriteLine();
}
}
公共类等级2:1级
{
}

和我引用该库在控制台应用程序包含以下内容:

 类节目
{
静态无效的主要(字串[] args)
{
变种C3 =新Class3中();
c3.Test();
Console.ReadKey();
}
}
公共类在Class3:ClassLibrary1.Class2
{
公共覆盖无效测试()
{
Console.WriteLine(控制台:在Class3 - 测试);
base.Test();
}
}



运行程序会输出如下:库 - 在Class3:1级 - 测试


  $ p> 

如果我建库的新版本,2.0.0版本,看起来像这样:

 公共类的Class1 
{
公共虚拟无效测试()
{
Console.WriteLine(图书馆:1级 - 测试V2);
Console.WriteLine();
}
}

公共类等级2:1级
{
公共覆盖无效测试()
{
Console.WriteLine (图书馆:等级2 - 测试V2);
base.Test();
}
}

和这个版本复制到bin文件夹中包含我的控制台程序并运行它,结果是:

 控制台:在Class3  - 测试
库:1级 - 测试V2

也就是说,从未执行Class2.Test方法,Class3.Test的base.Test调用似乎是势必Class1.Test因为控制台程序编译时Class2.Test并不存在。
这是非常令人惊讶的我,可能是在您部署库的新版本而无需重新编译应用程序的情况下的一个大问题。



没有任何人有这样的经历?



有没有什么好的解决办法?



这使得它诱人的增加空重写只是调用在案例库我需要在这一水平在未来添加一些代码...



编辑:



这似乎建立呼叫势必将在编译时的第一个现有的基本方法。我想知道为什么。如果我建立我的控制台程序与我的库的版本2的引用(这应该意味着调用编译调用Class2.Test),然后替换bin文件夹中的DLL版本1的是,预期的结果:

 控制台:在Class3  - 测试
库:1级 - 测试

所以没有运行时错误时Class2.Test不存在。为什么不能基地调用已编译调用Class2.Test摆在首位?



得到埃里克利珀或别人谁评论这将是有趣与编译器...


解决方案

作品这是我3月29日博客的主题:



HTTP: //blogs.msdn.com/ericlippert/archive/2010/03/29/putting-a-base-in-the-middle.aspx



原来,C#1.0做了它自己的方式,而这一决定引起了一些有趣的崩溃和性能问题。我们切换它做它在C#2.0中新的途径。



我学到了很多从这个问题。详见博客。


Lets say I have a library, version 1.0.0, with the following contents:

public class Class1
{
    public virtual void Test()
    {
        Console.WriteLine( "Library:Class1 - Test" );
        Console.WriteLine( "" );
    }
}
public class Class2 : Class1
{
}

and I reference this library in a console application with the following contents:

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();
    }
}

Running the program will output the following:

Console:Class3 - Test
Library:Class1 - Test

If I build a new version of the library, version 2.0.0, looking like this:

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();
    }
}

and copy this version to the bin folder containing my console program and run it, the results are:

Console:Class3 - Test
Library:Class1 - Test V2

I.e, the Class2.Test method is never executed, the base.Test call in Class3.Test seems to be bound to Class1.Test since Class2.Test didn't exist when the console program was compiled. This was very surprising to me and could be a big problem in situations where you deploy new versions of a library without recompiling applications.

Does anyone else have experience with this?

Are there any good solutions?

This makes it tempting to add empty overrides that just calls base in case I need to add some code at that level in the future...

Edit:

It seems to be established that the call is bound to the first existing base method at compile time. I wonder why. If I build my console program with a reference to version 2 of my library (which should mean that the call is compiled to invoke Class2.Test ) and then replace the dll in the bin folder with version 1 the result is, as expected:

Console:Class3 - Test
Library:Class1 - Test

So there is no runtime error when Class2.Test doesn't exist. Why couldn't the base call have been compiled to invoke Class2.Test in the first place?

It would be interesting to get a comment from Eric Lippert or someone else who works with the compiler...

解决方案

This was the subject of my blog on March 29th:

http://blogs.msdn.com/ericlippert/archive/2010/03/29/putting-a-base-in-the-middle.aspx

Turns out that C# 1.0 did it your way, and that this decision causes some interesting crashes and performance problems. We switched it to do it the new way in C# 2.0.

I learned a lot from this question. See the blog for details.

这篇关于方法绑定到外部库无法处理的新的虚拟方法&QUOT基方法...之间QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆