Similar to this question, I want to mix optional parameters with the params keyword, which of course creates ambiguity. Unfortunately, the answer of creating overloads does not work, as I want to take advantage of caller info attributes, like this:
public void Info(string message, [CallerMemberName] string memberName = "",
[CallerLineNumber] int lineNumber = 0, params object[] args)
{
_log.Info(BuildMessage(message, memberName, lineNumber), args);
}
Creating an overload without the optional parameters would change the call-site, preventing these particular parameters from working properly.
I found a solution that almost works (though it's ugly):
public void Info(string message, object arg0, [CallerMemberName] string memberName = "",
[CallerLineNumber] int lineNumber = 0)
{
_log.Info(BuildMessage(message, memberName, lineNumber), arg0);
}
public void Info(string message, object arg0, object arg1, [CallerMemberName] string memberName = "",
[CallerLineNumber] int lineNumber = 0)
{
_log.Info(BuildMessage(message, memberName, lineNumber), arg0, arg1);
}
The problem here is that if you specify a string for the last argument, the overload resolution assumes you're intending to explicitly specify memberName
in the overload that takes fewer arguments, which is not the desired behavior.
Is there some way to accomplish this (perhaps using some new attributes I haven't learned about?) or have we simply reached the limits of what the auto-magical compiler support can give us?
The definition of a method, constructor, indexer, or delegate can specify its parameters are required or optional. Any call must provide arguments for all required parameters, but can omit arguments for optional parameters. Each optional parameter has a default value as part of its definition.
The thing with optional parameters is, they are BAD because they are unintuitive - meaning they do NOT behave the way you would expect it. Here's why: They break ABI compatibility ! so you can change the default-arguments at one place.
It means we call method without passing the arguments. The optional parameter contains a default value in function definition. If we do not pass optional argument value at calling time, the default value is used.
Optional container object to have Java optional parametersIf a value is present, then the isPresent() method will return true, and the get() method will return the value. In case if we expect some null values, we can use the ofNullable() method of this class.
My prefered way: Only two charachters overhead - ugly language 'hack' though;
public delegate void WriteDelegate(string message, params object[] args);
public static WriteDelegate Info(
[CallerMemberName] string memberName = "",
[CallerLineNumber] int lineNumber = 0)
{
return new WriteDelegate ((message,args)=>
{
_log.Info(BuildMessage(message, memberName , lineNumber ), args);
});
}
Usage (supply your own implementation of BuildMessage
Info()("hello world {0} {1} {2}",1,2,3);
Alternative
The way my collegue came up to make this work was like this:
public static class DebugHelper
public static Tuple<string,int> GetCallerInfo(
[CallerMemberName] string memberName = "",
[CallerLineNumber] int lineNumber = 0)
{
return Tuple.Create(memberName,lineNumber);
}
}
The InfoMethod:
public void Info(Tuple<string,int> info, string message, params object[] args)
{
_log.Info(BuildMessage(message, info.Item1, info.Item2), args);
}
usage:
instance.Info(DebugHelper.GetCallerInfo(),"This is some test {0} {1} {2}",1,2,3);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With