Does the addition of optional method signature parameters increase and does the method exception throw an exception?

We have several projects that reference the library assembly, allows you to call "myUtil", now one of the methods referenced in several projects is

GetData(int p1, string p2, object p3, bool p4 = false); 

Now, if I go to this method above,

 GetData(int p1, string p2, object p3, bool p4 = false, bool p5 = false); 

Do I need to update the assembly "myUtil.dll" for projects that reference it?

WIthout referring to this, I get this error, which makes sense and disappears when I update the link , but I DO NOT ADD MY DIRECTION of the link, which says that you need to update the links

System.MissingMethodException: method not found: 'Void GetData (....

+7
c #
source share
3 answers

All links must be updated.

Optional parameters are just syntactic sugar.

If you have this:

 GetData(int p1, string p2, object p3, bool p4 = false); 

And name it as follows:

 GetData(1, "p2", obj); 

The compiler does this:

 GetData(1, "p2", obj, false); 

You will need to recompile and redeploy all the assemblies / projects that reference it.

+9
source share

You do not need to delete and re-add the link, but you need to rebuild all the projects that compile in the DLL. Adding an optional parameter is a source-compatible, but not binary-compatible change, since the compiler emits different ILs on the call site to include the standard value as normal - the call itself looks the same in IL, regardless of whether the additional parameter is omitted or not.

For example, consider the following code:

 class Test { static void Main() { Foo(3); Foo(); } static void Foo(int x = 5) { } } 

The IL for Main as follows:

  .method private hidebysig static void Main() cil managed { .entrypoint // Code size 16 (0x10) .maxstack 8 IL_0000: nop IL_0001: ldc.i4.3 IL_0002: call void Test::Foo(int32) IL_0007: nop IL_0008: ldc.i4.5 IL_0009: call void Test::Foo(int32) IL_000e: nop IL_000f: ret } // end of method Test::Main 

As you can see, constant 5 is loaded into the Main method and passed as an argument, just like 3 explicitly. The same thing happens at assembly boundaries.

The same rules also apply to changing constant values ​​and changing the default value for an optional parameter - this requires client rebuilds.

+8
source share

You can maintain compatibility if you stop using additional parameters and use method overloading instead:

 public void GetData(int p1, string p2, object p3, bool p4 = false, bool p5 = false) { //Do something } 

becomes

 public void GetData(int p1, string p2, object p3) { GetData(p1, p2, p3, false); } public void GetData(int p1, string p2, object p3, bool p4) { GetData(p1, p2, p3, p4, false); } public void GetData(int p1, string p2, object p3, bool p4, bool p5) { //Do something } 

However, this will not affect changing the default value unless you recompile all projects. For example, any old GetData(1, "2", null) will always call the new GetData(1, "2", null, false) , even if you change

 public void GetData(int p1, string p2, object p3) { GetData(p1, p2, p3, false); } 

to

 public void GetData(int p1, string p2, object p3) { GetData(p1, p2, p3, true); } 
+3
source share

All Articles