15

此处记录了属性和 C# 示例,但对于 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# 中执行上述操作,如果可以,表示法是什么?

4

2 回答 2

14

快速搜索编译器源代码,发现名称CallerMemberName没有出现在代码的任何地方,所以我认为不支持此功能。(您当然可以使用属性标记参数,但这些属性是特殊的 - 它们指示编译器,而不是在运行时以某种方式被发现和使用。)

2016 年 7 月更新:截至 6 月下旬,F# 现在支持 CallerLineNumberCallerFilePath,但CallerMemberName仍然不存在。不幸的是,似乎特别难以实施。

在相关的说明中,F# 有一些特殊的标识符,可让您获取当前的源文件名和行号,因此您可以使用__SOURCE_DIRECTORY__ and获得类似的信息__LINE__
(但不能像 C# 中那样从调用者获得)。

于 2013-01-02T11:48:14.867 回答
5

这是一个快速的'n'dirty hack,它滥用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
        | _ -> ()

它实际上或多或少地起作用:

在此处输入图像描述 在此处输入图像描述

于 2015-07-15T22:02:53.470 回答