Подтвердить что ты не робот

Можно ли использовать CallerMemberNameAttribute в f #

Здесь указаны атрибуты и примеры С#, но для FSharp это не выглядит.

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

// using System.Runtime.CompilerServices 
// using System.Diagnostics; 

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}

Пример вывода:

message: Something happened. 
member name: DoProcessing 
source file path: c:\Users\username\Documents\Visual Studio 2012\Projects\CallerInfoCS\CallerInfoCS\Form1.cs 
source line number: 31

Можно ли сделать выше в F #, и если да, то что такое обозначение?

4b9b3361

Ответ 1

Быстрый поиск через исходный код компилятора показывает, что имя CallerMemberName не отображается нигде в коде, поэтому я думаю, что это функция не поддерживается. (Вы можете, конечно, отметить параметр атрибутом, но эти атрибуты являются особыми - они инструктируют компилятор вместо того, чтобы быть обнаруженным и каким-то образом использоваться во время выполнения.)

Обновление июля 2016 года. По состоянию на конец июня F # теперь поддерживает CallerLineNumber и CallerFilePath, но CallerMemberName по-прежнему отсутствует. Похоже, что это, в частности, сложнее реализовать, к сожалению.

В соответствующей заметке F # имеет несколько специальных идентификаторов, которые позволяют получить текущее имя исходного файла и номер строки, чтобы вы могли получить аналогичную информацию с помощью __SOURCE_DIRECTORY__ и __LINE__
(но не от вызывающего, как в С#).

Ответ 2

Вот быстрый "n" грязный хак, который злоупотребляет inline, чтобы получить эту информацию:

module Tracing = 
    open System
    open System.Text.RegularExpressions

    let (|TraceInfo|_|) (s:string) =
        let m = Regex.Match(s, "at (?<mem>.+?) in (?<file>.+?\.[a-zA-Z]+):line (?<line>\d+)")
        if m.Success then
            Some(m.Groups.["mem"].Value, m.Groups.["file"].Value, int m.Groups.["line"].Value)
        else None

    let inline trace s =
        printfn "%s" s
        match Environment.StackTrace with
        | TraceInfo(m, f, l) ->
            printfn "  Member: %s" m
            printfn "  File  : %s" f
            printfn "  Line  : %d" l
        | _ -> ()

На самом деле это работает, более или менее:

enter image description hereenter image description here