Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing optional parameters and params when can't simply overload

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?

like image 448
Dan Bryant Avatar asked Jul 24 '14 14:07

Dan Bryant


People also ask

Can parameters be optional?

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.

Why are optional parameters bad?

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.

Why are optional parameters?

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.

How do you add optional parameters in Java?

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.


1 Answers

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);
like image 170
CSharpie Avatar answered Sep 19 '22 12:09

CSharpie