성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# 10 - (15) CallerArgumentExpression 특성 추가</h1> <p> 지난 C# 5.0에 호출자 정보로 다음의 3가지 특성이 제공되었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 5.0에 새로 추가된 Caller Info 특성 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/1134'>https://www.sysnet.pe.kr/2/0/1134</a> </pre> <br /> <ul> <li>CallerMemberName</li> <li>CallerFilePath</li> <li>CallerLineNumber</li> </ul> <br /> 그동안 이와 관련한 기능 추가가 없다가, C# 10에 들어서야 CallerArgumentExpression 특성 1개가 또 추가되는군요. ^^ 간단한 사용법을 보면 금방 어떤 것인지 이해가 되실 것입니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System.Runtime.CompilerServices; public static class Program { public static void Main(string [] args) { MyDebug.Assert(<span style='color: blue; font-weight: bold'>args.Length == 1</span>); MyDebug.Assert(<span style='color: blue; font-weight: bold'>Environment.CurrentDirectory == "c:/temp"</span>); } } public static class MyDebug { public static void Assert(bool <span style='color: blue; font-weight: bold'>condition</span>, <span style='color: blue; font-weight: bold'>[CallerArgumentExpression("condition")]</span> string message = null) { if (condition == false) { Console.WriteLine("Assert failed: " + message); } } } /* 출력 결과 Assert failed: <span style='color: blue; font-weight: bold'>args.Length == 1</span> Assert failed: <span style='color: blue; font-weight: bold'>Environment.CurrentDirectory == "c:/temp"</span> */ </pre> <br /> 보는 바와 같이 이전의 호출자 정보처럼 CallerArgumentExpression 특성이 붙은 인자는 기본값이 있어야 하고 그 특성에 전달된 "condition"은 해당 메서드에 전달된 또 다른 매개 변수의 이름이어야 합니다.<br /> <br /> C# 10 컴파일러는, 저렇게 CallerArgumentExpression이 지정된 메서드가 호출되면, 지정된 이름의 매개 변수로 전달된 표현식을 문자열 그대로 특성이 지정된 변수에 전달합니다. 즉, 위의 소스 코드를 C# 10 컴파일러는 다음과 같이 변환해 빌드하는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static class Program { public static void Main(string [] args) { MyDebug.Assert(args.Length == 1, <span style='color: blue; font-weight: bold'>"args.Length == 1"</span>); MyDebug.Assert(Environment.CurrentDirectory == "c:/temp", <span style='color: blue; font-weight: bold'>"Environment.CurrentDirectory == \"c:/temp\""</span>); } } </pre> <br /> 실제로 이 기능의 공식 문서에는 진단/테스트 API들에서의 오류 메시지 보완을 위한 것이라고 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > CallerArgumentExpression ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/caller-argument-expression'>https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/caller-argument-expression</a> Allow developers to capture the expressions passed to a method, to enable better error messages in diagnostic/testing APIs and reduce keystrokes. </pre> <br /> 따라서 단위 테스트나 로깅 프로젝트를 사용할 때 유용하게 사용할 수 있을 것입니다.<br /> <br /> 참고로 이 기능 역시 "<a target='tab' href='https://www.sysnet.pe.kr/2/0/12793'>C# 10 - (3) 개선된 변수 초기화 판정</a>"과 마찬가지로 Visual Studio 2022 Preview 3.1에서 빌드하면 .NET 5 + C# 9, .NET Framework + C# 10 프로젝트에서도 잘 동작합니다. 반면, Visual Studio 2019(16.11.1)에서 빌드하면 동작하지 않습니다.<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1864&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그나저나, 위와 같은 경우에 아쉽게도 CallerArgumentExpression에 인자의 이름을 문자열로 하드 코딩해 전달해야 하는 것을 nameof로 바꾸면 좋지 않을까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static void Assert(bool <span style='color: blue; font-weight: bold'>condition</span>, [CallerArgumentExpression(<span style='color: blue; font-weight: bold'>"condition"</span>)] string message = null) public static void Assert(bool <span style='color: blue; font-weight: bold'>condition</span>, [CallerArgumentExpression(<span style='color: blue; font-weight: bold'>nameof(condition)</span>)] string message = null) </pre> <br /> 저런 경우는 "<a target='tab' href='https://www.sysnet.pe.kr/2/0/12826'>C# 10 - (13) 문자열 보간 성능 개선</a>"에서도 InterpolatedStringHandlerArgument를 지정할 때도 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static string Create(IFormatProvider <span style='color: blue; font-weight: bold'>provider</span>, [InterpolatedStringHandlerArgument(<span style='color: blue; font-weight: bold'>"provider"</span>)] ref DefaultInterpolatedStringHandler handler) => handler.ToStringAndClear(); public static string Create(IFormatProvider <span style='color: blue; font-weight: bold'>provider</span>, [InterpolatedStringHandlerArgument(<span style='color: blue; font-weight: bold'>nameof(provider)</span>)] ref DefaultInterpolatedStringHandler handler) => handler.ToStringAndClear(); </pre> <br /> 아쉽게도 C# 10에서는 오류가 발생하지만, 현재 "<a target='tab' href='https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md#c-next'>C# Next</a>"로 "<a target='tab' href='https://github.com/dotnet/csharplang/issues/373'>nameof(parameter)</a>"가 예정돼 있으니 조금만 기다리시면 되겠습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 10 - (1) 구조체를 생성하는 record struct (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/record-structs'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4334'>Static Abstract Members In Interfaces C# 10 Preview)</a> ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12790'>https://www.sysnet.pe.kr/2/0/12790</a> C# 10 - (2) 전역 네임스페이스 선언 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/globalusingdirective'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/3428'>Global Using Directive</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12792'>https://www.sysnet.pe.kr/2/0/12792</a> C# 10 - (3) 개선된 변수 초기화 판정 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-definite-assignment'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4465'>Improved Definite Assignment</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12793'>https://www.sysnet.pe.kr/2/0/12793</a> C# 10 - (4) 상수 문자열에 포맷 식 사용 가능 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-interpolated-strings'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/2951'>Constant Interpolated Strings</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12796'>https://www.sysnet.pe.kr/2/0/12796</a> C# 10 - (5) 속성 패턴의 개선 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/extended-property-patterns'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4394'>Extended property patterns</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12799'>https://www.sysnet.pe.kr/2/0/12799</a> C# 10 - (6) record class 타입의 ToString 메서드를 sealed 처리 허용 (공식 문서, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4174'>Sealed record ToString</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12801'>https://www.sysnet.pe.kr/2/0/12801</a> C# 10 - (7) Source Generator V2 APIs (<a target='tab' href='https://github.com/dotnet/roslyn/issues/51257'>Source Generator V2 APIs</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12804'>https://www.sysnet.pe.kr/2/0/12804</a> C# 10 - (8) 분해 구문에서 기존 변수의 재사용 가능 (공식 문서, <a target='tab' href='https://github.com/dotnet/csharplang/issues/125'>Mix declarations and variables in deconstruction</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12805'>https://www.sysnet.pe.kr/2/0/12805</a> C# 10 - (9) 비동기 메서드가 사용할 AsyncMethodBuilder 선택 가능 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/1407'>Async method builder override</a>); ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12807'>https://www.sysnet.pe.kr/2/0/12807</a> C# 10 - (10) 개선된 #line 지시자 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/enhanced-line-directives'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4747'>Enhanced #line directive</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12812'>https://www.sysnet.pe.kr/2/0/12812</a> C# 10 - (11) Lambda 개선 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/lambda-improvements'>공식 문서 1</a>, <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/lambda-attributes'>공식 문서 2</a>, <a target='tab' href='https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md'>Lambda improvements</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12813'>https://www.sysnet.pe.kr/2/0/12813</a> C# 10 - (12) 문자열 보간 성능 개선 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-interpolated-strings'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/4487'>Interpolated string improvements</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12826'>https://www.sysnet.pe.kr/2/0/12826</a> C# 10 - (13) 단일 파일 내에 적용되는 namespace 선언 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/file-scoped-namespaces'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/137'>File-scoped namespace</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12828'>https://www.sysnet.pe.kr/2/0/12828</a> C# 10 - (14) 구조체 타입에 기본 생성자 정의 가능 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/parameterless-struct-constructors'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/99'>Parameterless struct constructors</a>) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12829'>https://www.sysnet.pe.kr/2/0/12829</a> C# 10 - (15) CallerArgumentExpression 특성 추가 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/caller-argument-expression'>공식 문서</a>, <a target='tab' href='https://github.com/dotnet/csharplang/issues/287'>Caller expression attribute</a>) ; https://www.sysnet.pe.kr/2/0/12835 Language Feature Status ; <a target='tab' href='https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md'>https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md</a> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9856
(왼쪽의 숫자를 입력해야 합니다.)