I suggest you ...

Caller/MemberName/FilePath/LineNumber of .NET 4.5 are not usable in a real tracing API

The new .NET 4.5 attributes CallerMemberName, CallerFilePath and CallerLineNumber are nice but do not play well with methods that have a format string with a variable argument array like Trace(string fmt, .... params [] object args). It would be helpful to support tracing in a meaningful manner by allowing

Trace(string fmt, .... params [] object args, [CallerLineNumberAttribute] int line )

The only way out of this would be to support many overloads which is not nice from the Api usabality point of view.

97 votes
Vote
Sign in
(thinking…)
Password icon
Signed in as (Sign out)
You have left! (?) (thinking…)
Alois Kraus shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

Thanks for taking the time to share this suggestion. This item has been around for a couple of versions of Visual Studio and we haven’t acted on it. Looking at the VS “15” plans, we’re not going to take action on this item, so we’re going to close it. If the suggestion is still relevant, please either take a look to see if there’s another suggestion that’s similar that you can vote on, or open a new suggestion.

- The Visual Studio Team

6 comments

Sign in
(thinking…)
Password icon
Signed in as (Sign out)
Submitting...
  • Anonymous commented  ·   ·  Flag as inappropriate

    As a workaround, people could use Anotar, or other Fody extensions, which works well with params and complexities not possible with CallerInfoAttributes. Besides, the advantage is that the weaving can be totally isolated, without runtime dependencies.

    Just my 2c.

  • PK commented  ·   ·  Flag as inappropriate

    Only work around I could find is creating a wrapper class:

    public class CallerInfo
    {
    public readonly string MemberName;
    public readonly int LineNumber;

    public CallerInfo(
    [CallerMemberName] string memberName = "",
    [CallerLineNumber] int lineNumber = 0)
    {
    MemberName = memberName;
    LineNumber = lineNumber;
    }
    }

    And then make your Trace signature:

    void Trace(string format, CallerInfo callerInfo, params object[] args);

    When you call it:

    Trace("Trace message: {0}", new CallerInfo(), "Message");

    Yes it's dumb.

  • Anonymous commented  ·   ·  Flag as inappropriate

    @Anonymous you can't move the line parameter before it because then all your calls to Trace would blow up expecting everything to provide the line if they want to provide arguments i.e.
    Trace(string fmt, [CallerLineNumberAttribute] int line = 0, params object[] args)

    Then callling:
    Trace("Hi {0}", "world")

    Would not work because Trace expects an int as the second argument.

  • Alois Kraus commented  ·   ·  Flag as inappropriate

    This does not work from a user perspective. You cannot wrap it with a helper method since File and Line are taken from the call site.

    Trace("Hi {0}", "world");

    should be possible. If I follow your advice I would need to write something like
    Trace("Hi {0}", Line:152, File:"Sample.cs", "world");

    where you loose the ability to let the compiler fill in the missing gaps.

  • Lukas commented  ·   ·  Flag as inappropriate

    A params[] always must be the last parameter of a method definition. If you move your "line" parameter before it, then it should work.

Feedback and Knowledge Base