C# 试图理解跨越程序集的方法签名更改
我们在促销时遇到了一个奇怪的问题,我希望我能用代码来解释它。我想了解它为什么会这样做 大会1C# 试图理解跨越程序集的方法签名更改,c#,.net,dll,dependencies,.net-assembly,C#,.net,Dll,Dependencies,.net Assembly,我们在促销时遇到了一个奇怪的问题,我希望我能用代码来解释它。我想了解它为什么会这样做 大会1 public static class Foo { public static string DoStuff() { // Do something return "some string"; } } 大会2: public class Bar { public void SomeMethod() { // I
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";
}
}
这一重新编译很好,程序集2能够成功地利用更改的方法签名,而无需抱怨。执行了我的签入,并升级了具有更改的项目dll(注意,这只是程序集1 dll)
升级后,我们发现程序集2在Foo.DoStuff()调用上失败-不幸的是,我无法提供异常,因为上面的代码正在吞噬它
尽管汇编2中没有实际的代码更改,但它似乎确实在重新编译时对dll产生了影响,即使方法签名(至少在我看来)是相同的,因为为新参数提供了默认值
我使用dotnet peek查看“旧dll”和“新dll”(尽管该程序集没有代码更改,并且确实注意到两个dll中的差异,即在旧dll中,没有提供默认值参数,但在重新编译中,提供了默认值参数
我想我的问题可以归结为:
- 假设您将方法签名从
更改为Foo(long x)
,但在调用站点,您仅将其称为Foo(int x)
…它在两种情况下都编译,但编译为不同的代码Foo(5)
- 假设您将一个方法签名从
更改为Foo(intx,inty)
,并调用Foo(inty,intx)
…再次,代码的含义从Foo(x:5,y:2)
更改为Foo(5,2)
,如果您明白我的意思的话。根据新代码重新编译未更改的源代码“接收”代码将改变行为Foo(2,5)
- 假设程序集1中有一个常量,例如
。如果将其更改为public const string Foo=“Foo”
,但不使用该常量重新编译程序集,则这些程序集仍将使用“Foo”值(这也适用于可选参数的默认值)public const string Foo=“Bar”
- 假设您将方法签名从
更改为Foo(long x)
,但在调用站点,您仅将其称为Foo(int x)
…它在两种情况下都编译,但编译为不同的代码Foo(5)
- 假设您将方法签名从
更改为Foo(intx,inty)
,并调用Foo(inty,intx)
…再次,代码的含义从Foo(x:5,y:2)
更改为Foo(5,2)
,如果您明白我的意思的话。根据新的接收“代码”将改变行为Foo(2,5)
- 假设程序集1中有一个常量,例如
。如果将其更改为public const string Foo=“Foo”
,但不使用该常量重新编译程序集,则这些程序集仍将使用“Foo”值(这也适用于可选参数的默认值)public const string Foo=“Bar”