성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
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# 8.0의 #nulable 관련 특성을 .NET Framework 프로젝트에서 사용하는 방법</h1> <p> <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8'>C# 8.0의 신규 문법</a> 중에서 .NET Core 3.0이 아닌 .NET Framework에서 사용할 수 없는 구문이 4가지입니다.<br /> <br /> <ol> <li><a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams'>기본 인터페이스 메서드</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams'>비동기 스트림</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams'>#nullable 지시자와 nullable 참조 형식</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#indices-and-ranges'>새로운 연산자 - 인덱스, 범위</a></li> </ol> <br /> 이 중에서 1번은 .NET Core 3.0에서만 가능하고, 2번은 NuGet으로부터 System.Interactive.Async 어셈블리를 참조 추가하면 되고, 나머지 2개는 개발자가 타입을 정의해 주면 사용할 수 있습니다. 이 중에서 4번에 대해서는 설명한 적이 있는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 8.0의 Index/Range 연산자를 .NET Framework에서 사용하는 방법 및 비동기 스트림의 컴파일 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11835'>http://www.sysnet.pe.kr/2/0/11835</a> Visual Studio 2019 Preview 4/RC - C# 8.0 Missing compiler required member 'System.Range..ctor' ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11836'>http://www.sysnet.pe.kr/2/0/11836</a> </pre> <br /> 이번에는 3번에 대해서 설명하려고 합니다. ^^<br /> <br /> 우선 이를 위해 C# 8.0 컴파일러를 활성화하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Framework 프로젝트에서 C# 8.0 컴파일러를 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/12033'>http://www.sysnet.pe.kr/2/0/12033</a> </pre> <br /> 소스 코드에 다음과 같이 null 체크에 대한 NotNullWhen 특성을 사용하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>#nullable enable</span> using System.Diagnostics.CodeAnalysis; class Program { public string? Name = ""; static void Main(string[] args) { Program pg = new Program(); GetLengthOfName(pg); } static int GetLengthOfName(Program person) { /* IsNull 코드를 빼면, 그 아래의 person.Name.Length에서 null 참조 경고 발생 */ if (IsNull(person.Name)) { return 0; } return person.Name.Length; } static bool IsNull(<span style='color: blue; font-weight: bold'>[NotNullWhen(false)]</span> string? value) { if (value == null) { return true; } return false; } } </pre> <br /> NotNullWhen 타입(및 그 외 8개의 특성)이,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Update libraries to use nullable reference types and communicate nullable rules to callers ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/csharp/nullable-attributes'>https://learn.microsoft.com/en-us/dotnet/csharp/nullable-attributes</a> </pre> <br /> .NET Framework 4.8 BCL에는 포함되어 있지 않으므로 컴파일 오류가 발생합니다. 다행히 특성에 불과하기 때문에 다음과 같이 관련 타입들을 추가해 주면 .NET Framework 용 프로젝트에서도 사용할 수 있습니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // Attributes for nullable annotations // <a target='tab' href='https://github.com/dotnet/corefx/issues/37826'>https://github.com/dotnet/corefx/issues/37826</a> namespace System.Diagnostics.CodeAnalysis { /// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] public sealed class AllowNullAttribute : Attribute { } /// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] public sealed class DisallowNullAttribute : Attribute { } /// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] public sealed class MaybeNullAttribute : Attribute { } /// <summary>Specifies that an output will not be null even if the corresponding type allows it.</summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] public sealed class NotNullAttribute : Attribute { } /// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary> [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] public sealed class MaybeNullWhenAttribute : Attribute { /// <summary>Initializes the attribute with the specified return value condition.</summary> /// <param name="returnValue"> /// The return value condition. If the method returns this value, the associated parameter may be null. /// </param> public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; /// <summary>Gets the return value condition.</summary> public bool ReturnValue { get; } } /// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary> [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] public sealed class NotNullWhenAttribute : Attribute { /// <summary>Initializes the attribute with the specified return value condition.</summary> /// <param name="returnValue"> /// The return value condition. If the method returns this value, the associated parameter will not be null. /// </param> public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; /// <summary>Gets the return value condition.</summary> public bool ReturnValue { get; } } /// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary> [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)] public sealed class NotNullIfNotNullAttribute : Attribute { /// <summary>Initializes the attribute with the associated parameter name.</summary> /// <param name="parameterName"> /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. /// </param> public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName ?? throw new ArgumentNullException(nameof(parameterName)); } /// <summary>Gets the associated parameter name.</summary> public string ParameterName { get; } } /// <summary>Applied to a method that will never return under any circumstance.</summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public sealed class DoesNotReturnAttribute : Attribute { } /// <summary>Specifies that the method will not return if the associated Boolean property is passed the specified value.</summary> [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true)] public sealed class DoesNotReturnIfAttribute : Attribute { /// <summary>Initializes the attribute.</summary> /// <param name="parameterValue"> /// The condition parameter value. Code after the method will be unreachable if the argument to the associated parameter /// matches this value. /// </param> public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; /// <summary>Gets the condition parameter value.</summary> public bool ParameterValue { get; } } } </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1506&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2103
(왼쪽의 숫자를 입력해야 합니다.)