Study/TIL(Today I Learned)

24.08.07 C#

에린_1 2024. 8. 7. 19:40
728x90

24.08.07 C#

C#

Sealed

sealed 클래스

  • C#에서 클래스 또는 메서드에 적용할 수 있는 키워드로, 주로 상속과 관련된 기능을 제어하는 데 사용된다.
  • sealed 키워드를 클래스에 적용하면 그 클래스를 상속할 수 없게 된다. 상속하려고 하면 컴파일러가 오류를 발생시킨다. 이는 특정 클래스가 더 이상 파생 클래스를 가질 필요가 없거나, 의도적으로 확장을 제한하고자 할 대 유용하다.

sealed 메서드

  • sealed 키워드는 메서드에도 사용할 수 있으며, 이 경우에는 override 키워드와 함께 사용된다. sealed 키워드를 사용해서 메서드를 재정의하면, 해당 메서드를 더 이상 하위 클래스에서 재정의할 수 없게 된다.

사용 이유

  • 보안 및 무결성
    • 특정 클래스나 메서드가 더 이상 변경되지 않도록 하여 프로그램의 무결성을 보호할 수 있다.
  • 최적화
    • JIT 컴파일러는 sealed 클래스를 더 효율적으로 최적화할 수 있다. 상속이 불가능하므로 객체가 특정 클래스의 인스턴스임을 보장할 수 있으며, 이에 따라 최적화할 수 있다.

GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE

  • Google Protocol Buffers(프로토콜 버퍼) 라이브러리와 관련된 환경 변수 또는 컴파일러 설정으로, 주로 .NET 환경에서 사용된다. 이 설정은 프로토콜 버퍼 코드가 .NET의 ref struct와의 호환성 모드를 활성화할지 여부를 결정한다.

ref struct

  • ref struct는 C# 7.2부터 도입된 구조체(struct)의 특별한 종류이다. 다음과 같은 특징을 갖는다.
    1. 스택에 할당
      • 힙이 아닌 스택에 할당된다. 따라서 ref struct는 스택 프레임이 유효할 때만 유효한 객체를 나타낸다.
    2. ref 나 out으로만 전달
      • ref struct는 참조로만 전달될 수 있으며, ref나 out 키워드를 사용하여 메서드 매개변수로 전달된다.
    3. 제약 조건
      • ref struct는 박싱(boxing)되지 않으며, 인터페이스를 구현할 수 없고, 힙에서 관리되지 않는다. 이는 메모리 안정성을 보장하고, 특정 메모리 관리 패턴을 강제하는 데 사용된다.

GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE

  • 이 환경 변수 또는 설정은 프로토콜 버퍼 라이브러리가 ref struct를 사용할 때의 호환성을 제어한다. 프로토콜 버퍼는 메시지 직렬화와 역직렬화에 사용되며, .NET 환경에서 더 효율적인 메모리 사용과 성능을 위해 ref struct를 사용하거나, 이를 피하고 전통적인 구조체를 사용할 수 있는 옵션을 제공한다.

설정 효과

  1. 활성화
    • GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE가 활성화된 경우, 프로토콜 버퍼 라이브러리는 ref struct를 사용하는 방법으로 컴파일되어 메모리 관리 및 성능 최적화를 추구할 수 있다. 하지만 이는 ref struct의 제약(박싱 불가, 인터페이스 구현 불가 등)을 받아들여야 함을 의미한다.
  2. 비활성화
    • 이 모드가 비활성화된 경우, 프로토콜 버퍼 라이브러르는 일반적인 구조체나 클래스를 사용하여 보다 유연한 사용이 가능하지만, 그만큼 메모리 관리 및 성능에서의 이점을 포기할 수 있다.

사용 예

  • 일반적으로, 이 모드의 사용 여부는 라이브러리 개발자가 결정하며, 특정 상황에서는 개발자가 설정을 변경할 수 있다. 예를 들어, 코드가 .NET Standard에서 실행되는 경우, .NET Core와 .NET Framework 간의 호환성을 유지하기 위해 ref struct 사용을 피할 수 있다.

UnknownFieldSet

  • Google Protocol Buffers(프로토콜 버퍼) 라이브러리의 기능 중 하나로, 메시지 형식의 필드 정의에 포함되지 않은 필드를 처리하기 위한 구조체 또는 클래스이다. 프로토콜 버퍼 메시지를 직렬화하고 역직렬화할 때, 정의되지 않은 필드 또는 알 수 없는 필드가 있을 수 있다. 이러한 필드는 UnknownFieldSet을 통해 관리된다.

주요 기능

  1. 미지의 필드 저장
    • UnknownFieldSet는 메시지를 역직렬화하는 동안 메시지 형식에 정의되지 않은 필드를 저장한다. 이는 메시지 구조가 변경된 후에도 역방향 호환성을 유지할 수 있도록 도와준다. 예를 들어, 메시지 형식이 업데이트되어 새로운 필드가 추가되었지만, 이전 버전의 시스템에서도 해당 메시지를 수신하고 처리할 수 있다.
  2. 직렬화 및 역직렬화
    • 미지의 필드는 직렬화 과정에서 원래 형태 그대로 보존된다. 이렇게 하면 원래 메시지 형식을 다시 사용하는 경우, 원래 필드 데이터가 손실되지 않고 복원될 수 있다.
  3. 호환성 유지
    • 새로운 필드가 추가된 메시지가 이전 버전의 시스템에 의해 수신될 때, 알 수 없는 필드는 무시되지 않고 UnknownFieldSet에 저장된다. 이렇게 하면 이후에 해당 필드를 필요로 하는 시스템이 올바르게 동작할 수 있다.

주요 메서드 및 속성

  • AddField
    • 미지의 필드를 추가한다.
  • Clear
    • 모든 미지의 필드를 제거한다.
  • MergeFrom
    • 다른 UnknownFieldSet에서 데이터를 병합한다.
  • ToByteArray
    • UnknownFieldSet의 내용을 바이트 배열로 직렬화한다.

ProtoMsg.ProtocolMessageReflection.Descriptor.MessageTypes

  • Google Protocol Buffers(프로토콜 버퍼)에서 특정 메시지 타입의 메타데이터를 접근하는 데 사용되는 코드 구조이다. 이를 통해 프로토콜 버퍼 정의 파일(.proto 파일)에 정의된 메시지 타입들의 정보를 반영(reflection) 메커니즘을 통해 얻을 수 있다.

구성요소

  1. ProtoMsg
    • 보통 이 이름은 네임스페이스를 나타내며, 개발자가 정의한 프로토콜 버퍼 메시지 파일에서 생성된 코드와 관련이 있다. 예를 들어, ProtoMsg는 protocol.proto라는 파일에서 생성된 C# 코드를 담는 네임스페이스일 수 있다.
  2. ProtocolMessageReflection
    • 이 클래스는 프로토콜 버퍼 컴파일러가 생성한 정적 클래스이다. 이 클래스는 해당 .proto 파일과 관련된 모든 메타데이터를 포함하고 있으며, 메시지, 열거형, 서버스 등에 대한 정보에 접근할 수 있다.
  3. Descriptor
    • 이 속성은 프로토콜 버퍼 정의와 관련된 다양한 정보와 메타데이터를 담고 있는 클래스이다. Descriptor는 .proto 파일의 내용(메시지, 필드, 열거형 등)에 대한 구조적 정보를 제공한다.
  4. MessageTypes
    • Descriptor 클래스의 속성 중 하나로, 정의된 모든 메시지 타입들의 정보를 담고 있는 컬렉션이다. 이는 각 메시지 타입의 메타데이터를 MessageDescriptor 객체로 제공한다.

활용

  • 이 반영(reflection) API는 런타임에 프로토콜 버퍼 메시지의 구조를 탐색하거나 조작해야 할 때 유용하다. 예를 들어, 메시지의 특정 필드를 동적으로 설정하거나, 메시지의 구조를 동적으로 생성하고자 할 대 사용될 수 있다. 이는 특히 유연한 시스템을 설계할 때, 메시지 포맷의 변경에 대응하거나, 다양한 메시지 타입을 처리할 때 매우 유용하다.

JsonFormatter.ToDiagnosticString

  • Google Protocol Buffes에서 제공하는 JSON 직렬화 기능의 일부로, 프로토콜 버퍼 메시지를 사람이 읽을 수 있는 JSON 문자열 형식으로 변환하는 메서드이다. 주로 디버깅 및 로깅 목적으로 사용되며, 메시지의 내용을 쉽게 확인할 수 있도록 도와준다.

주요 특징

  1. 가독성
    • ToDiagnosticString은 메시지의 필드 값을 사람이 읽기 쉬운 형식으로 변환한다. 이는 일반적인 JSON 직렬화 출력보다 가독성을 높이기 위한 것이다.
  2. 디버깅 용도
    • 메시지의 내부 상태를 쉽게 확인할 수 있도록 설계되어 있어, 디버깅 과정에서 유용하게 사용할 수 있다.
  3. 형식
    • 일반적으로 JSON 형식의 문자열로 반환되며, 이는 JSON 구문을 지원하는 대부분의 텍스트 뷰어나 디버깅 도구에서 쉽게 해석할 수 있다.

주의 사항

  • 디버깅 목적
    • ToDiagnosticString은 주로 디버깅 및 로깅 용도로 사용되며, 프로덕션 환경에서 사용되는 JSON 직렬화 포맷과 다를 수 있다.
  • 데이터 민감성
    • 출력된 JSON 문자열은 디버깅 정보로 포함될 수 있으므로,민감한 데이터를 포함할 경우 주의가 필요하다.

MergeFrom

  • Google Protocol Buffers(프로토콜 버퍼)에서 사용되는 메서드로, 두 개의 메시지 인스턴스를 병합하는 데 사용된다. 주로 두 메시지를 하나로 결합하여 누락된 필드를 채우거나, 한 메시지의 필드를 다른 메시지로 덮어쓰는 작업을 수행할 때 사용된다.

주요 특징

  1. 메시지 병합
    • MergeFrom은 소스 메시지의 필드를 대상 메시지로 복사한다. 이는 소스 메시지에서 설정된 필드만 복사되며, 대상 메시지에서 이미 존재하는 필드 값을 덮어쓰지 않는다.
  2. 필드 추가
    • 대상 메시지에 소스 메시지의 필드가 존재하지 않을 경우, 해당 필드를 추가한다.
  3. 복합 필드 병합
    • 반복되는 필드나 중첩된 메시지 같은 복합 필드는 소스 메시지의 항목을 대상 메시지의 항목에 추가하는 방식으로 병합된다.

동작 방식

  • 스칼라 값 필드
    • 기본형(예: int, bool) 필드의 경우, 소스 메시지의 필드 값이 대상 메시지의 필드 값을 덮어쓴다.
  • 반복 필드
    • 배열이나 리스트와 같은 반복 필드의 경우, 소스 메시지의 항목이 대상 메시지의 리스트에 추가된다.
  • 중첩 메시지
    • 중첩된 메시지의 경우, 소스 메시지의 중첩된 메시지가 대상 메시지의 중첩된 메시지와 병합된다.

주의 사항

  • MergeFrom 메서드는 항상 대상 메시지를 수정한다. 원래의 대상 메시지에 있던 값은 덮어쓰거나 추가되는 필드에 의해 변경될 수 있다.
  • 이 메서드는 프로토콜 버퍼 메시지 간에 데이터를 결합하거나 업데이트할 때 유용하지만, 잘못 사용하면 의도치 않은 필드에 의해 데이터 손실이 발생할 수 있다.
728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.08.09 C#,DEV  (0) 2024.08.09
24.08.08 Dev, C#  (0) 2024.08.08
24.08.06 C#, 젠킨스  (0) 2024.08.06
24.08.05 C#  (0) 2024.08.05
24.08.02 C#, DEV  (0) 2024.08.02