DynamoDB 테이블에서 읽어서 채워지는 DTO가 있습니다. 현재 다음과 같이 가정하십시오.
public class Item
{
public string Id { get; set; } // PK so technically cannot be null
public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
public string Description { get; set; } // can be null
}
이를 처리하기 위해 개발할 모범 사례가 있습니까? 매개 변수가없는 생성자는 Dynamo SDK의 ORM (및 기타)에서 제대로 작동하지 않기 때문에 오히려 매개 변수가없는 생성자를 피하고 싶습니다.
PK public string Id { get; set; } = "";
이기 때문에 결코 발생 Id
하지 않으며 결코 null 이 될 수 없기 때문에 글을 쓰는 것이 이상하게 보입니다 . ""
어쨌든 어떻게 되었더라도 어떤 용도로 사용 됩니까?
이에 대한 모범 사례는 무엇입니까?
- 그들
string?
중 일부는 결코 없어야하지만 null이 될 수 있다고 말해야합니다. - 나는 초기화해야
Id
와Name
함께""
그들이 있기 때문에 해야 널 (null)이 쇼 결코 의도는 비록""
사용되지 않을 것입니다. - 위의 일부 조합
참고 : 이것은 C # 8 nullable 참조 유형 에 관한 것입니다.
답변
옵션으로 default
리터럴을null forgiving operator
public class Item
{
public string Id { get; set; } = default!;
public string Name { get; set; } = default!;
public string Description { get; set; } = default!;
}
DTO가 DynamoDB에서 채워 지므로 MaybeNull/NotNull
사후 조건 속성 을 사용하여 null 가능성을 제어 할 수 있습니다
MaybeNull
널 입력 불가능 리턴 값은 널일 수 있습니다.NotNull
nullable 반환 값은 null이되지 않습니다.
그러나 이러한 특성은 주석이 달린 구성원의 발신자에 대한 Null 허용 분석에만 영향을줍니다. 일반적으로 이러한 속성을 메서드 반환, 속성 및 인덱서 게터에 적용합니다.
따라서 모든 속성을 null이 아닌 속성으로 간주하고 MaybeNull
속성으로 장식하여 가능한 null
값을 반환 함을 나타낼 수 있습니다
public class Item
{
public string Id { get; set; } = "";
[MaybeNull] public string Name { get; set; } = default!;
[MaybeNull] public string Description { get; set; } = default!;
}
다음 예제는 업데이트 된 Item
클래스 의 사용법을 보여줍니다 . 보시다시피, 두 번째 줄에는 경고가 표시되지 않지만 세 번째 줄에는 경고가 표시됩니다
var item = new Item();
string id = item.Id;
string name = item.Name; //warning CS8600: Converting null literal or possible null value to non-nullable type.
또는 모든 속성을 nullable 속성으로 만들고 NoNull
반환 값을 표시 할 수 없습니다 null
( Id
예 :).
public class Item
{
[NotNull] public string? Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
}
경고는 이전 예제와 동일합니다.
입력 매개 변수, 속성 및 인덱서 세터에 대한 AllowNull/DisallowNull
사전 조건 특성 도 비슷한 방식으로 작동합니다.
AllowNull
널 입력 불가능 입력 인수는 널일 수 있습니다.DisallowNull
널 입력 가능 인수는 널이 아니어야합니다.
클래스가 데이터베이스에서 채워지기 때문에 도움이 될 것이라고 생각하지 않지만 첫 번째 옵션에서 이와 같이 속성 설정 기의 Null 허용 여부를 제어하는 데 사용할 수 있습니다
[MaybeNull, AllowNull] public string Description { get; set; }
그리고 두 번째
[NotNull, DisallowNull] public string? Id { get; set; }
post / preconditions에 대한 몇 가지 유용한 세부 사항과 예제는이 devblog 기사 에서 찾을 수 있습니다.
답변
이 시나리오의 교과서 대답은을 사용하는 것입니다 string?
당신을 위해 Id
재산, 그러나 또한 로 장식 [NotNull]
속성 :
public class Item
{
[NotNull] public string? Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
}
참조 : 에 따른 문서 의
[NotNull]
속성 “이 출력되지 않도록 지정은 대응하는 형태가 허용하는 경우에도 널 (null).”
그래서 여기서 정확히 무슨 일이 일어나고 있습니까?
- 첫째,
string?
반환 유형은 생성 중에 속성이 초기화되지 않았다는 컴파일러의 경고를 표시하지 않으므로 기본값 은로 설정 됩니다null
. - 그런 다음
[NotNull]
속성을 null이 아닌 변수에 속성을 할당하거나 참조를 해제하려고 할 때 경고를 방지합니다 . 실제로 컴파일러의 정적 흐름 분석 에 실제로이 속성은 절대로 적용되지 않습니다null
.
경고 : C #의 Null 허용 컨텍스트와 관련된 모든 경우와 마찬가지로 기술적으로 여전히
null
값을 반환하지 못하게 하여 다운 스트림 예외가 발생할 가능성이 없습니다. 즉, 즉시 사용 가능한 런타임 유효성 검사가 없습니다. 모든 C #은 컴파일러 경고입니다. 소개[NotNull]
할 때 비즈니스 로직에 대한 힌트를 제공하여 경고를 효과적으로 무시합니다. 이와 같이, 당신이 가진 속성에 주석을 때[NotNull]
, 당신은 당신의 약속에 대한 책임을 복용 “이 것 결코 부터 발생하지Id
PK가하고 null이 될 수 없다을.”
이러한 약속을 유지하기 위해 속성에 속성에 주석을 추가 할 수 있습니다 [DisallowNull]
.
public class Item
{
[NotNull, DisallowNull] public string? Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
}
참조 : 에 따른 문서 의
[DisallowNull]
속성 “지정null
입력으로 허용되고 대응하는 유형을 허용하더라도.”
값이 데이터베이스를 통해 할당되고 있기 때문에 이것은 귀하의 경우와 관련없는,하지만 [DisallowNull]
혹시 대입 할 때 속성은 당신에게 경고를 줄 것이다 null
에 (수) 값을 Id
, 이 수의 반환 형식은 달리 할 수에도 불구하고 널 (null) . 이와 관련하여, Id
작용 것이다 정확히 유사한 string
반면, C #까지의 정적 흐름 분석뿐만 우려 같은 값이 대상의 구조와 특성 사이의 인구 초기화되지 않은 상태를 유지하도록 허용한다.
참고 : 다른 사람들이 언급했듯이
Id
기본값default!
또는 중 하나를 기본값 으로 지정하면 사실상 동일한 결과를 얻을 수 있습니다null!
. 이것은 분명히 문체 선호도입니다. 더 명확하고 세부적인 제어 기능을 제공하기 때문에 Null 허용 주석을 사용하는 것을 선호하지만!
컴파일러를 종료하는 방법으로 남용하기 쉽습니다 . 값을 사용하여 속성을 명시 적으로 초기화하면 해당 값을 기본값으로 사용하지 않더라도 절대 사용하지 않을 것입니다.
답변
문자열은 참조 유형이며 항상 nullable이므로 특별한 작업을 수행 할 필요가 없습니다. 이 객체 유형을 다른 객체 유형에 매핑하려는 경우 나중에 문제가 발생할 수 있지만 나중에 처리 할 수 있습니다.