【发布时间】:2015-06-13 22:15:53
【问题描述】:
我们在促销时遇到了一个奇怪的问题,我希望我能用代码来解释它。我想了解它为什么会这样。
组装 1
public static class Foo
{
public static string DoStuff()
{
// Do something
return "some string";
}
}
组装 2:
public class Bar
{
public void SomeMethod()
{
// I realize the below is not what should be done for catching exceptions, as the exception is never thrown due to the return, and seems unnecessary either way...
// this is inherited code and has not been modified to correct.
try
{
var someValue = Foo.DoStuff();
}
catch (Exception)
{
return;
throw;
}
}
}
要求发生了变化,因此 DoStuff 需要接受一个参数,该参数的值会稍微改变行为。请注意,只有程序集 1.Foo 正在更改。
新符
public static class Foo
{
public static string DoStuff(bool someBool = false)
{
// Do something
return "some string";
}
}
这重新编译得很好,Assembly 2 能够成功地使用更改后的方法签名而没有抱怨。我的签入已执行,并提升了有更改的项目 dll(请注意,这只是 Assembly 1 dll)。
升级后,我们发现 Assembly 2 在 Foo.DoStuff() 调用上失败 - 不幸的是,我无法提供异常,因为上面的代码正在吞噬它。
尽管在 Assembly 2 中没有实际代码更改,但它似乎确实对重新编译时的 dll 产生了影响,即使方法签名(至少在我看来)是相同的,因为为新的提供了默认值参数。
我使用 dotnet peek 来查看“旧 dll”和“新 dll”(即使没有对该程序集进行任何代码更改,并且确实注意到旧 DLL 中的两个 DLL 存在差异,默认没有提供 value 参数,但在重新编译时,提供了默认 value 参数。
我想我的问题可以归结为:
- 为什么程序集 2 上的已编译代码会根据(至少我认为)应该是透明的方法签名进行更改?
- 避免这种情况的方法是否只是“部署一切”?而不是尝试根据代码更改进行部署?请注意,未签入 DLL,因此程序集 2 没有实际的“代码更改”,尽管 DLL 根据对程序集 1 的更改而有所不同。
【问题讨论】:
-
避免这种情况的另一种方法是保留无参数方法并让它使用默认值调用新方法,而不是在方法签名中指定默认值:
public static string DoStuff() { return DoStuff(false); }.从该捕获中删除return也将有所帮助(或至少首先记录异常)。 -
@RufusL 如果我能再次做到这一切,知道我现在所知道的,那肯定是我会采取的方法;)
标签: c# .net dll dependencies .net-assembly