Информация об изменениях

Сообщение Re: Логгинг с именами функций и номерами строк от 16.08.2017 13:58

Изменено 16.08.2017 14:03 kov_serg

Re: Логгинг с именами функций и номерами строк
Здравствуйте, BigBoss, Вы писали:

BB>Как известно, __LINE__, __FILE__ вместе с макро в C# не попали.

BB>StackFrame медленный и вообще не должен компилироваться в native (не пробовал, но рефлексии там вроде нет).
BB>К версии 4.5 появились System.Runtime.CompilerServices, но "в лоб" это тоже не работает. Вариации на тему

BB>
BB>    void LogMessage(string format, object[] args,
BB>        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
BB>        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
BB>        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
BB>    {
BB>        string msg = string.Format(format, args);
BB>        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, msg);
BB>    }
BB>

BB>компилируется, но естественно не так, как хотелось бы, аттрибуты на сопоставление параметров не влияют. Попробуйте сами

BB>
BB>    LogMessage("Hello, world");
BB>    LogMessage("Hello, {0}", "world");
BB>    LogMessage("{0}, {1}", "Hello", "world");
BB>

BB>А как (можно ли вообще) на C# написать функцию вроде LogMessage, но работающую и без черезмерного синтаксического оверхеда?
using System;
using System.Runtime.CompilerServices;
using System.Globalization;

public static class StringFmtExt {
    public static string fmt(this string fmt,params object[] args)
    {
        return string.Format(CultureInfo.InvariantCulture,fmt,args);
    }
}

public class Test {

    static void Log(string msg,
            [CallerMemberName] string memberName="",
            [CallerFilePath] string sourceFilePath="",
            [CallerLineNumber] int sourceLineNumber=0
    )
    {
        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, msg);
    }
    
    public delegate void LogDelegate(string fmt,params object[] args);
    static LogDelegate LogPoint(
        [CallerMemberName] string memberName="",
        [CallerFilePath] string sourceFilePath="",
        [CallerLineNumber] int sourceLineNumber=0) 
    {
        return (fmt,args)=>{
            var text=string.Format(CultureInfo.InvariantCulture,fmt,args);
            Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, text);
        };
    }

    static void Log0(string fmt, object[] args,
            [CallerMemberName] string memberName="",
            [CallerFilePath] string sourceFilePath="",
            [CallerLineNumber] int sourceLineNumber=0
    )
    {
        var text=string.Format(CultureInfo.InvariantCulture,fmt,args);
        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, text);
    }
    
    public static void Main()
    {
        Log("test {0} {1}".fmt(1,2));
        LogPoint()("test {0} {1}",1,2);
        Log0("text {0} {1}",new object[] { 1,2 });
    }
}

prog.cs Main:47 'test 1 2'
prog.cs Main:48 'test 1 2'
prog.cs Main:49 'text 1 2'
Re: Логгинг с именами функций и номерами строк
Здравствуйте, BigBoss, Вы писали:

BB>Как известно, __LINE__, __FILE__ вместе с макро в C# не попали.

BB>StackFrame медленный и вообще не должен компилироваться в native (не пробовал, но рефлексии там вроде нет).
BB>К версии 4.5 появились System.Runtime.CompilerServices, но "в лоб" это тоже не работает. Вариации на тему

BB>
BB>    void LogMessage(string format, object[] args,
BB>        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
BB>        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
BB>        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
BB>    {
BB>        string msg = string.Format(format, args);
BB>        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, msg);
BB>    }
BB>

BB>компилируется, но естественно не так, как хотелось бы, аттрибуты на сопоставление параметров не влияют. Попробуйте сами

BB>
BB>    LogMessage("Hello, world");
BB>    LogMessage("Hello, {0}", "world");
BB>    LogMessage("{0}, {1}", "Hello", "world");
BB>

BB>А как (можно ли вообще) на C# написать функцию вроде LogMessage, но работающую и без черезмерного синтаксического оверхеда?
using System;
using System.Runtime.CompilerServices;
using System.Globalization;

public static class StringFmtExt {
    public static string fmt(this string fmt,params object[] args)
    {
        return string.Format(CultureInfo.InvariantCulture,fmt,args);
    }
}

public class Test {

    static void Log(string msg,
            [CallerMemberName] string memberName="",
            [CallerFilePath] string sourceFilePath="",
            [CallerLineNumber] int sourceLineNumber=0
    )
    {
        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, msg);
    }
    
    public delegate void LogDelegate(string fmt,params object[] args);
    static LogDelegate LogPoint(
        [CallerMemberName] string memberName="",
        [CallerFilePath] string sourceFilePath="",
        [CallerLineNumber] int sourceLineNumber=0) 
    {
        return (fmt,args)=>{
            var text=string.Format(CultureInfo.InvariantCulture,fmt,args);
            Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, text);
        };
    }
    static void Debug(Action<LogDelegate> op,
        [CallerMemberName] string memberName="",
        [CallerFilePath] string sourceFilePath="",
        [CallerLineNumber] int sourceLineNumber=0) 
    {
        op( (fmt,args)=>{
            var text=string.Format(CultureInfo.InvariantCulture,fmt,args);
            Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, text);
        });
    }

    static void Log0(string fmt, object[] args,
            [CallerMemberName] string memberName="",
            [CallerFilePath] string sourceFilePath="",
            [CallerLineNumber] int sourceLineNumber=0
    )
    {
        var text=string.Format(CultureInfo.InvariantCulture,fmt,args);
        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, text);
    }
    
    public static void Main()
    {
        Log("test {0} {1}".fmt(1,2));
        LogPoint()("test {0} {1}",1,2);
        Log0("test {0} {1}",new object[] { 1,2 });
        Debug(log=>log("test {0} {1}",1,2));
    }
}

prog.cs Main:57 'test 1 2'
prog.cs Main:58 'test 1 2'
prog.cs Main:59 'test 1 2'
prog.cs Main:60 'test 1 2'