reflaxe.CSharp icon indicating copy to clipboard operation
reflaxe.CSharp copied to clipboard

Optional arguments and C#

Open jeremyfa opened this issue 1 year ago • 13 comments

Let's assume we have this Haxe method that has one optional argument followed with a required one:

function foo(optInt:Int = 4, reqString:String) {
	// ...
}

In Haxe this is valid. (I believe @Simn was thinking about maybe removing that feature in favor of overload at some point).

Anyway, the naive C# output would be:

public virtual void foo(int optInt = 4, string reqString) {
	// ...
}

But that is not valid in C# because optional args need to be after the required ones.

In current C# target, it would handle that situation by making every argument non-optional in the C# method, but wrap every haxe optional arg into haxe.lang.Null. The above example gives that in current C# target:

public virtual void foo(global::haxe.lang.Null<int> optInt, string reqString) {
	unchecked {
		int optInt1 = ( ( ! (optInt.hasValue) ) ? (4) : ((optInt).@value) );
	}
	#line default
}

Then when you call with haxe foo("hello");, it would become foo(default(global::haxe.lang.Null<int>), "hello") in output to match the C# method.

This isn't ideal because wrapping with haxe.lang.Null primitive types means creating garbage memory even if it is definitely not needed: an int with a default value should never be null anyway.

In the new Reflaxe/C# target I'd like to explore another approach: solving that case with C# overload. The above method with optional arg could generate this C# code instead:

public virtual void foo(string reqString) {
	foo(4, reqString);
}

public virtual void foo(int optInt, string reqString) {
	// ...
}

Then no need to do anything special when calling as one or the other signature should be resolved depending on the arguments provided.

Will need to confirm that later, but it might make it easier to deal with reflection as well (I know there are also issues with dynamic calls and optional args in current C# target).

jeremyfa avatar Apr 25 '23 21:04 jeremyfa