기본 생성자를 숨기기 위해 스트러크를 클래스로 맹목적으로 변환합니까?
-
07-07-2019 - |
문제
이 주제와 관련된 모든 질문을 읽었으며 모두 기본 생성자가 struct
C#에서는 사용할 수 없지만이 상황에 직면 할 때 일반적인 행동 과정을 제안하는 사람은 아직 찾지 못했습니다.
명백한 해결책은 간단히 변환하는 것입니다 struct
a class
결과를 다루십시오.
그것을 유지하기위한 다른 옵션이 있습니까? struct
?
내부 상업 API 객체 중 하나와 함께이 상황에 도달했습니다. 디자이너는 그것을 a에서 변환했습니다 class
a struct
, 그리고 이제는 기본 생성자 (이전에 개인)가 객체를 유효하지 않은 상태로 남겨 둡니다.
나는 우리가 물체를 struct
, 국가의 유효성을 점검하는 메커니즘을 도입해야합니다 ( IsValid
재산). 나는 많은 저항에 만났고, "API를 사용하는 사람은 기본 생성자를 사용해서는 안된다"는 설명이었다. (참고 : 해당 물체는 정적 공장 방법을 통해 "올바르게"구성되며 다른 모든 생성자는 다음과 같습니다. internal
.)
모두가 단순히 그들의 변환입니다 struct
s to class
이 상황에서 두 번째 생각없이?
편집 :이 유형의 객체를 struct
- 위의 해당 물체는 struct
보다 class
.
해결책
a struct
, 당신은 유형을 설계하여 기본 구성 인스턴스 (필드 모두 0)가 유효한 상태입니다. 당신은 [그렇지 않을 것이다] 임의로 사용합니다 struct
대신에 class
정당한 이유없이 - 불변의 참조 유형을 사용하는 데 아무런 문제가 없습니다.
내 제안 :
- a를 사용하는 이유를 확인하십시오
struct
유효합니다 ([실제] 프로파일 러는 매우 가벼운 물체의 많은 할당으로 인한 중대한 성능 문제를 나타 냈습니다). - 기본 구성 인스턴스가 유효하도록 유형을 설계하십시오.
- 유형의 디자인이 Native/Com Interop 제약 조건에 의해 지시되면 기능을 감싸고 노출하지 마십시오.
struct
래퍼 외부 (개인 중첩 유형). 이렇게하면 제한된 유형 요구 사항의 적절한 사용을 쉽게 문서화하고 확인할 수 있습니다.
다른 팁
그 이유는 struct (system.valuetype의 인스턴스)가 CLR에 의해 특별히 처리되기 때문입니다. 모든 필드가 0 (또는 기본값)으로 초기화됩니다. 당신은 실제로 하나를 만들 필요조차 없습니다 - 그냥 선언하십시오. 이것이 기본 생성자가 필요한 이유입니다.
두 가지 방법 으로이 문제를 해결할 수 있습니다.
- IsValid와 같은 속성을 만들어서 귀하가 나타내는 것처럼 유효한 구조물인지 표시하고
- .NET 2.0에서 nullable 사용을 고려하십시오u003CT> 비 초기화 (null) 구조물을 허용합니다.
구조물을 클래스로 변경하면 매우 미묘한 결과 (멀티 스레드 환경에서 더 많은 메모리 사용 및 객체 아이덴티티 측면에서), 비 이질적이지만 비 초기의 개체에 대한 NullReferenceExceptions를 디버깅하기가 어렵습니다.
기본 생성자를 정의 할 가능성이없는 이유는 다음 표현으로 설명됩니다.
new MyStruct[1000];
여기에는 3 가지 옵션이 있습니다
- 기본 생성자를 1000 번 호출합니다
- 손상된 데이터 생성 (구조물에 참조가 포함될 수 있습니다. 참조를 초기화하거나 비워 두지 않으면 임의의 메모리에 잠재적으로 액세스 할 수 있음) 또는
- 제로로 할당 된 메모리를 비우십시오 (바이트 레벨).
.NET은 스트러크와 클래스 모두에 대해 동일하게 수행합니다. 필드와 어레이 요소는 제로로 비워집니다. 이것은 또한 structs와 classe 사이에 더 일관된 행동을 취하며 안전하지 않은 코드가 없습니다. 또한 .NET 프레임 워크가 new byte[1000]
.
그리고 그것은 structs .net의 기본 생성자입니다 .NET은 자체를 요구하고 처리합니다.
이제이를 처리하려면 몇 가지 옵션이 있습니다.
- 구조물에 AM-I Initialized 속성을 추가하십시오 (예 :
HasValue
~에Nullable
). - 제로화 된 구조물을 유효한 값으로 허용하십시오 (예 : 0은 10 진수의 유효한 값입니다).