Main behaves differently between LINQPad & LPRun
This is a follow-on from my comment to “Help! LPRun.exe exceptions not setting %errorlevel%” thread…
I ran into a strange difference between how
Yet another different I've found is that I can define optional arguments on my
I ran into a strange difference between how
Main
behaves under LINQPad and under LPRun and I am not sure the discrepancy is intentional. It seems that you can return any type of value from Main
, not just an integer, and LINQPad will still happily run it (i.e. accepts the signature of the entry-point) and displays the returned value in the Results pane. For example, if I return a sequence (an IEnumerable<>
of some T
) from Main
then it gets displayed. LPRun, on the other hand, discards the returned value. It's as if LINQPad has a much more relaxed definition of Main
than C# would accept and I was taking advantage of it until I realised that LPRun behaves differently. Since I stumbled on this by sheer accident, it makes me wonder if this is a bug or a feature. Moreover, if the issue with returning an exit code from Main
ever gets fixed, I'm worried about it introducing a breaking change in my scripts.Yet another different I've found is that I can define optional arguments on my
Main
, e.g.:
This works perfectly under LINQPad but LPRun breaks with an error:
void Main(string[] args, int x = 10)
{
// ...
}
ArgumentException: Object of type 'System.String' cannot be converted to type 'System.String[]'.
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at LINQPad.ExecutionModel.ClrQueryRunner.Run()
at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner)
Comments
- LPRun
- Util.Run
With Util.Run, you can pass and return richly-typed arguments, whereas with LPRun, you are restricted to passing in string[] args and returning an integer (because that's how the command-line works).
If you want to call your script from the command-line, you should stick to the simple signature, otherwise feel free to use the full C# type system.
Util.Run
since I have never used or had the need for it.