programing

현재 회선 번호는 어떻게 알 수 있나요?

telecom 2023. 4. 10. 20:55
반응형

현재 회선 번호는 어떻게 알 수 있나요?

다음은 제가 하고 싶은 일의 예입니다.

MessageBox.Show("Error line number " + CurrentLineNumber);

위의 코드로CurrentLineNumber는, 이 코드의 소스 코드의 회선 번호입니다.

내가 어떻게 그럴 수 있을까?

.NET 4.5 / C# 5 에서는, 새로운 발신자 속성을 사용하는 유틸리티 메서드를 기술하는 것으로, 컴파일러에 이 작업을 의뢰할 수 있습니다.

using System.Runtime.CompilerServices;

static void SomeMethodSomewhere()
{
    ShowMessage("Boo");
}
...
static void ShowMessage(string message,
    [CallerLineNumber] int lineNumber = 0,
    [CallerMemberName] string caller = null)
{
     MessageBox.Show(message + " at line " + lineNumber + " (" + caller + ")");
}

다음과 같이 표시됩니다.

39회선의 BOO(Some Method Somewhere)

그리고 또[CallerFilePath]원래 코드 파일의 경로를 알려줍니다.

Stack Frame 을 사용합니다.Get File Line Number 메서드는 다음과 같습니다.

private static void ReportError(string message)
{
     StackFrame callStack = new StackFrame(1, true);
     MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName() 
          + ", Line: " + callStack.GetFileLineNumber());
}

자세한 내용은 Scott Hanselman의 블로그 항목을 참조하십시오.

[편집: 다음 추가]

를 사용하는 사용자용.Net 4.5 이후로는 시스템의 Caller File Path, Caller Method Name 및 Caller Line Number Atribute를 검토합니다.런타임컴파일러 서비스 이름 공간입니다.예를 들어 다음과 같습니다.

public void TraceMessage(string message,
        [CallerMemberName] string callingMethod = "",
        [CallerFilePath] string callingFilePath = "",
        [CallerLineNumber] int callingFileLineNumber = 0)
{
    // Write out message
}

인수는 다음과 같아야 합니다.string위해서CallerMemberName그리고.CallerFilePath그리고int위해서CallerLineNumber디폴트값이 필요합니다.메서드 파라미터에 이러한 속성을 지정하면 컴파일러는 컴파일 시에 적절한 값을 호출 코드에 삽입하도록 지시됩니다.즉, 이 값은 난독화에 의해 동작합니다.상세한 것에 대하여는, 「발신자 정보」를 참조해 주세요.

라이너 한 척을 선호하기 때문에:

int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();

.NET 4.5에서는 다음 함수를 생성하여 회선 번호를 얻을 수 있습니다.

static int LineNumber([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
    return lineNumber; 
}

그럼 전화할 때마다LineNumber()현재의 라인이 표시됩니다.이는 StackTrace를 사용하는 모든 솔루션보다 디버깅과 릴리스 모두에서 동작할 수 있다는 장점이 있습니다.

따라서, 필요한 것에 대한 최초의 요구를 취하면, 다음과 같이 됩니다.

MessageBox.Show("Error enter code here line number " + LineNumber());

이것은 마크 그라벨의 훌륭한 답변을 바탕으로 하고 있다.

가 필요한 사용자용.NET 4.0+ 메서드 솔루션:

using System;
using System.IO;
using System.Diagnostics;

public static void Log(string message) {
   StackFrame stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1);
   string fileName = stackFrame.GetFileName();
   string methodName = stackFrame.GetMethod().ToString();
   int lineNumber = stackFrame.GetFileLineNumber();

   Console.WriteLine("{0}({1}:{2})\n{3}", methodName, Path.GetFileName(fileName), lineNumber, message);
}

문의처:

void Test() {
   Log("Look here!");
}

출력:

Void Test() (FILENAME.cs:104)

이것 봐!

콘솔을 변경합니다.원하는 대로 WriteLine 포맷!

만약 시도 캐치블록에 있다면 이것을 사용하세요.

try
{
    //Do something
}
catch (Exception ex)
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
    Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}

회선번호와 null 가능한 프로젝트 유형만 물어봤을 때 다음과 같은 것을 사용해야 합니다.

internal class Utils
{
   public static int Line([CallerLineNumber] int? lineNumber =null)=>lineNumber;
}

당신의 코드로 회선번호를 알고 싶으면 그냥 전화하세요.

var line=Utils.Line();

로깅 중 회선번호를 기록하려면 다음과 같은 메서드를 호출하지 마십시오.

public void MyMethod(int someValue)
{
    switch(someValue)
    { 
        case 1:
            if(abc<xyz)
            {
             logger.LogInformation("case value {someValue} this line {line} was true", someValue ,Utils.Line()-2);
            }
            break;

        case 2:
           logger.LogInformation("case value {someValue} this {line} was executed",someValue,Utils.Line());
           break;
        caste 3:
           logger.LogInformation("case value {someValue} this {line} was executed",someValue,Utils.Line());
           break;
    }
}

이 패턴은 다른 [CallerXXX]방식으로 확장할 수 있으며 메서드 파라미터뿐만 아니라 어디서도 사용할 수 없습니다.

Nuget 패키지에서 Walter I는 ExceptionObject라는 이름의 매우 멋진 클래스를 사용합니다.

NuGet 패키지를 Import하면 Exception 클래스에 적절한 확장 메서드가 몇 가지 있을 뿐만 아니라 메서드파라미터 및 호출된 모든 메서드의 파라미터 값을 포함한 콜체인을 표시하는 CallStack에 액세스 할 수 있습니다.

이는 어떤 값으로 어떤 결과를 얻었는지를 보여주는 값만을 가진 예외의 스택과 같습니다.

public void MyMethod()
{
    try
    {
    
      //get me all methods, signatures, parameters line numbers file names etc used as well as assembly info of all assemblies used for documentation of how the code got here
      var stack= new CallStack();
      foreach( var frame in StackedFrames)
      {
         logger.LogDebug(frame.ToString());
      }
    }
    catch(SqlException e)
    {
       var ex = new ExceptionObject(e);
       logger.LogException(e,"{this} exception due to {message} {server} {procedure} TSQL-line:{sqlline}\n{TSQL}"
                            ,e.GetType().Name
                            ,e.Message
                            ,ex.SqlServer
                            ,ex.SqlProcedureName
                            ,ex.SqlLineNumber
                            ,ex.Tsql
                            ,ex.CallStack); 
    }
    catch(Exception e)
    {
       var ex = new ExceptionObject(e);
       logger.LogException(e,"{this} exception due to {message} signature: signature}\nCallStack:", e.GetType().Name,e.Message,ex.Signature,ex.CallStack); 
    }
}

언급URL : https://stackoverflow.com/questions/12556767/how-do-i-get-the-current-line-number

반응형