🔸 Syntactic Sugar

Syntactic Sugar란, 코딩 문법은 그대로인데, 코드를 읽는 사람이 직관적으로 쉽게 코드를 읽을 수 있게 만든 것이다.

위키피디아에서는 이를 인간이 사용하기에 언어를 "더 달콤하게" 만든다.라고 표현하고 있다.

이를 통해 생산성과 가독성 두 마리 토끼를 모두 챙길 수 있다는 장점이 있다.

이런 Syntactic Sugar는 다양한 언어에서 지원되고 있는데,

흔히 볼 수 있는 예로는 다음과 같은 코드들이 있다.

아래 코드는 다르게 작성되었지만, 모두 x에 1을 더하는 작업이다.

x = x + 1;
x += 1;
x++;

요약하면,

  • 프로그래밍 언어 차원에서 제공되는 논리적으로 간결하게 표현하는 것
  • 중복되는 로직을 간결하게 표현하기 위해 나타나게 되었다.



🔸 C#에서는

그렇다면 C#에서 지원하는 Syntactic Sugar에는 어떤 것들이 있을까?

다양한 기능들이 존재하지만, 여기서는 자주 쓸만하다고 생각 하는 것들을 정리해서 공유하기로 한다.


🔹 List Pattern (C# 11.0)

List에서 패턴 매칭을 진행할 때, 사용 할 수 있는 방법이다.

슬라이스 패턴 (..)과, 무시 패턴 (_)을 통해 리스트가 특정 패턴에 매칭되는지 확인하는 방법이다.

예를 들어, 아래와 같이 선언되었다고 하자.

int[] arr1 = { 1, 2, 10 };
int[] arr2 = { 1, 2, 5, 10 };
int[] arr3 = { 1, 2, 5, 6, 7, 8, 9, 10 };

이 경우, 이 배열들은 모두 [1, 2, .., 10] 이라는 패턴과 일치한다.

Console.WriteLine(CheckSwitch(arr1)); // 1
Console.WriteLine(CheckSwitch(arr2)); // 1
Console.WriteLine(CheckSwitch(arr3)); // 1

static int CheckSwitch(int[] values) => values switch
{
    [1, 2, .., 10] => 1,
    [..] => 0                    // default
};

위 예제에서는 switch문에 List Pattern을 사용하고 있는데, 이때에는 default와 같은 경우를 위해 [..]를 추가해야한다.

(없으면 경고가 뜬다고 한다.)

또 다른 예로, 아래와 같은 배열이 선언되었다고 하자.

int[] arr4 = { 1, 3 };
int[] arr5 = { 1, 3, 6 };
int[] arr6 = { 2, 3 };

이 경우, 다음과 같은 출력을 보인다.

Console.WriteLine(arr4 is [1, _]);       // true
Console.WriteLine(arr5 is [1, ..]);      // true
Console.WriteLine(arr6 is [..]);         // true

이러한 List Pattern은 IList 인터페이스를 구현하고 있으면 사용할 수 있다고 한다.


🔹 File-Scoped Namespace Declaration (C# 10.0)

파일 전체에 적용되는 namespace를 정의하는 방법이다.

아래와 같은 코드가 있을 때, namespace를 사용함으로써 코드 전체에 들여쓰기가 한 번 적용된다.

using System;

namespace MyProject {
    public class MyClass{
        // 중략
    }
}

이는 다음과 같이 표현 할 수 있다.

namespace MyProject;
using System;

public class MyClass{
    // 중략
}


🔹 Global Using Statement (C# 10.0)

모든 프로젝트에 적용되는 using 구문을 추가 할 수 있다.

// Global Using statements

// .NET default namespaces
global using System;
global using System.Collections.Generic;

모든 프로젝트의 파일에 적용되므로, 따로 파일을 만들어 관리하는것이 좋아보인다.


🔹 with (비파괴적 변경) (C# 9.0 / C# 10.0)

값을 분해하거나 새로 정의할 필요 없이, 특정 원소만 바꿀 때 사용 할 수 있다.

C# 9.0에서 with 식의 왼쪽 피연산자는 레코드 형식이어야 하나,

C# 10부터 with 식의 왼쪽 피연산자가 구조체 형식 또는 무명 형식일 수도 있다고 한다.

// Windows.UI.Color
public struct Color : IFormattable
{
    public byte A, R, G, B;
}

// 사용자 설정
Color color = Colors.Azure; // 해당 색상의 ARGB값 대입됨

// 투명도 조절
Color semiTransparent = color with { A = 120 };


🔹 매개변수 한정자 in (C# 7.2)

C#에서 메서드 매개 변수를 선언할 때 사용할 수 있는 키워드들로, 다음 4가지가 존재한다.

  • params :매개 변수가 가변 개수의 인수를 사용할 수 있음을 지정
  • ref : 매개 변수를 참조로 전달할 수 있고 호출된 메서드로 읽거나 쓸 수 있음을 지정
  • out : 매개 변수가 참조로 전달되고 호출된 메서드에 의해 기록되도록 지정
  • in : 이 매개 변수를 참조로 전달할 수 있지만 호출된 메서드로만 읽을 수 있음을 지정


이 중, in의 경우, 매개변수를 전달할 때 수정이 불가능한 readonly로 전달된다는 점이다.

메서드 내부에서 읽기 쓰기
ref 가능 가능
in 가능 불가능
out 가능 반드시 해야함



📚 레퍼런스

[Javascript] syntactic sugar란 무엇인가?

[MSDN] 식 사용 - 비파괴적 변경은 수정된 속성을 사용하여 새 개체를 생성

C# 11 - 목록 패턴(List patterns)

[C#10.0] C#의 편리한 구문들 모음 (Syntax Sugar)

The New “in” Keyword For C# 7.2