출처: https://baba-s.hatenablog.com/entry/2020/09/01/090000?utm_source=feed

아직은 .NET Standard 2.1 미지원 등으로 인해 C# 8.0의 모든 기능을 사용할 수는 없고 일부 아래 기능들만 사용할 수 있다.

C# 8.0의 새로운 기능

읽기 전용 멤버

using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       
var character = new Character();
       Debug.Log(character.Name);
       Debug.Log(character.GetName());
   }
}

public struct Character
{
   
// ★
   
public readonly string Name => "피카츄";

   
// ★
   
public readonly string GetName() => "피카츄";
}

switch 식

using System;
using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       Debug.Log(GetName(3));
// CCC
   }

   
private string GetName(int i)
   {
       
// ★
       
return i switch
       {
           1 =>
"AAA",
           2 =>
"BBB",
           3 =>
"CCC",
           _ =>
throw new ArgumentException(),
       };
   }
}

프로퍼티 패턴

using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       Debug.Log(GetName(Vector2Int.up));
// 상
   }

   
private string GetName(Vector2Int vec)
   {
       
// ★
       
return vec switch
       {
           { x: -1, y:  0 } =>
"좌",
           { x:  1, y:  0 } =>
"우",
           { x:  0, y:  1 } =>
"상",
           { x:  0, y: -1 } =>
"하",
       };
   }
}

tuple 패턴

using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       Debug.Log(GetName(0, 1));
// 상
   }

   
private string GetName(int x, int y)
   {
       
// ★
       
return (x, y) switch
       {
           { x: -1, y:  0 } =>
"좌",
           { x:  1, y:  0 } =>
"우",
           { x:  0, y:  1 } =>
"상",
           { x:  0, y: -1 } =>
"하",
       };
   }
}

위치 지정 패턴

using UnityEngine;

public static class Vector2IntExt
{
   
public static void Deconstruct
   (
       
this Vector2Int self,
       
out float x,
       
out float y
   )
   {
       x = self.x;
       y = self.y;
   }
}

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       Debug.Log(GetName(Vector2Int.up));
// 상
   }

   
private string GetName(Vector2Int vec)
   {
       
// ★
       
return vec switch
       {
           
var (x, y) when x < 0 && y == 0 => "좌",
           
var (x, y) when 0 < x && y == 0 => "우",
           
var (x, y) when x == 0 && 0 < y => "상",
           
var (x, y) when x == 0 && y < 0 => "하",
       };
   }
}

using 선언

using System;
using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       
// ★
       
using var character = new Character();

       Debug.Log(
"피카츄");

       
// Awake 함수를 나올 때 「AAA」 라고 출력된다
   }
}

public class Character : IDisposable
{
   
public void Dispose()
   {
       Debug.Log(
"AAA");
   }
}

정적 로컬 함수

using System;
using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       
// ★
       
static string GetName() => "피카츄";

       Debug.Log(GetName());
   }
}

null 허용 참조 타입

using UnityEngine;

// ★
#nullable enable

public class Example : MonoBehaviour
{
   
// ★
   
string? GetName() => null;

   
private void Awake()
   {
       Debug.Log(GetName());
   }
}

null 합체 할당

using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       
string name = null;

       
// ★
       Debug.Log( name ??=
"AAA" ); // AAA
       Debug.Log( name ??=
"BBB" ); // AA
   }
}

verbatim 보간 문자열 확장

using UnityEngine;

public class Example : MonoBehaviour
{
   
private void Awake()
   {
       
var dir = "tmp";
       Debug.Log(
$@"C:\{dir}" ); // C# 7.3 이전도 사용 가능
       Debug.Log( @
$"C:\{dir}" ); // C# 8 이후부터 사용 가능
   }
}

Visual Studio 2019가 필요

Visual Studio 2017은 기본적으로 C# 8.0 에 대응하지 않기 때문에

Unity 2020.2a + Visual Studio에서 C# 8.0을 사용하고 싶은 경우는 Visual Studio 2019를 설치해야 한다.

Visual Studio 2017 에서 C# 8.0 사용하는 방법

https://stackoverflow.com/questions/54701377/how-can-i-use-c-sharp-8-with-visual-studio-2017

.csproj 언어 버전에 8.0을 지정하는 에디터 확장이 필요

Unity 2020.2.0a21 에서 .csproj를 생성하면 생성된 .csproj의 언어 버전이 7.3 으로 되어 있어서 C# 8.0의 기능을 사용하여 코딩하면 Visual Studio 측에서 에러가 표시된다.

https://forum.unity.com/threads/unity-c-8-support.663757/page-4#post-5963279 

위 페이지에서 공개되어 있는 에디터 확장을 Unity 프로젝트에 추가하면 생성되는  .csproj 의 언어 버전이 8.0으로 바뀐다.

에디터 확장 스크립트(인용)

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using UnityEditor;

internal sealed class EnsureCSharp8Postprocessor : AssetPostprocessor
{
   
private static string OnGeneratedCSProject(string path, string content)
   {
       
var document = XDocument.Parse(content);

       
var root = document.Root;
       
if (root is null)
           
throw new ArgumentNullException(nameof(root));

       
var ns = root.GetDefaultNamespace();

       
var element = root.Descendants(ns + "LangVersion").SingleOrDefault();
       
if (element == null)
           
throw new ArgumentNullException(nameof(element));

       element.Value =
"8.0";

       
using (var writer = new Utf8StringWriter())
       {
           document.Save(writer);

           content = writer.ToString();
       }

       
return content;
   }

   
private sealed class Utf8StringWriter : StringWriter
   {
       
public override Encoding Encoding => Encoding.UTF8;
   }
}