Mac 사용자를 위한 C#으로 개발할 때 좋은 도구
C#으로 개발할 때 좋은 도구를 추천해보고자 합니다.
Mac 사용자 기준으로 작성된 글입니다.
가장 유명한 통합 개발 환경(IDE)
가장 유명한 것은 Visual Studio, Rider입니다. 모두 유용한 기능이 많고 아주 훌륭하고 편리한 도구입니다.
Windows 환경이시라면 큰 고민 없이 마음에 드는 IDE를 시작하셔도 무방합니다.
실리콘 Mac에서는 Visual Studio가 성능이 별로고 Mac 환경에 딱히 친화적이지 않아서 JetBrains에서 만든 Rider를 그냥 쓰라고 추천받고는 했는데요. Mac용 Visual Studio 2022부터는 많은 것이 개선되었습니다.
Visual Studio 특유의 환경과 IntelliSence를 좋아한다면 새로 나온 Visual Studio for Mac 2022를 사용해보셔도 될 것 같아요.
자세하게 한번 비교를 해보겠습니다.
* 예전에 Unity에 내장되어 있어서 유명했던 Open Source 편집기인 MonoDevelop도 있습니다.
Visual Studio와 Rider의 비교
1. Visual Studio for Mac 2022

마이크로소프트에서 만든 IDE입니다.
Rosetta2를 사용하지 않고 Apple Silicon(ARM64) 프로세서에 대한 기본 지원이 됩니다!!
예전에 Rosetta2로 돌아가던 구버전 Visual Studio는 켜지는 것도 답답하고 파일 목록 불러오는데도 느리면 10초 정도 기다려야 해서 답답했던 기억이 있습니다.
제가 이전에 Windows와 Visual Studio를 2년 넘게 쓰고 작업하면서 단축키도 많이 외우고 IntelliSence에 상황에서 Mac으로 넘어갔었습니다. 그 당시에는 Mac용 Visual Studio가 너무 답답하고 느려서 JetBrains 제품으로 넘어가버렸습니다.
그래도 이제는 Apple Silicon이 지원되면서 와... 정말 빨라졌습니다.
이게 정말 체감되더라고요.
사실 많이 테스트해보지는 않았지만 기본적으로 모든 동작이 정말 빨라졌습니다.빨리 업데이트해줬다면 안 넘어갔을텐데ㅠ
Mac 사용자를 위한 UX도 개선되어서 더 쾌적하게 느껴졌습니다.
Visual Studio는 학생(혹은 개인)이면 무료로 사용할 수 있습니다.
Mac용 Visual Studio 2022는 Windows용 Visual Studio에 비해 일부 기능이 제한됩니다.

Unity를 하거나 기본적인 C# 공부를 하는 데는 아무런 지장이 없습니다.
MAUI(구 Xamarin)을 작업을 하는 데에도 좋습니다.
2. Rider

JetBrains에서 만든 .Net용 IDE입니다.
IntelliJ, PyCharm, CLion 같은 JetBrains 제품에 익숙하시다면 고민 없이 Rider를!!
JetBrains은 IDE를 만드는 회사입니다. JetBrains 특유의 사용법이 있어서 하나의 제품에 익숙해진다면 다른 JetBrains 사용법도 비슷해서 금방 익힙니다. 그리고 IDE의 기능도 전체적으로 완성도가 높습니다. 가끔 새로운 유용한 기능을 발견할 때마다 상당히 많은 고민과 연구를 했겠구나 싶었습니다.
기능이 편리하게 잘 되어있어서 리팩터링, Git 기능(Cherry Pick, PR 등), 원격 작업, 등을 상당히 편리하게 사용할 수 있습니다. 이런 유용한 기능과 옵션이 너무 많아서 잘 모를 수도 있지만 교육 영상이나 기능을 익힐 수 있게 많은 장치들이 있어서 자연스럽게 시간이 지나면서 더 많이 익히고 고인물이 됩니다.
단축키도 편리하게 되어있습니다. Shift-Shift, Ctrl-Ctrl, Cmd-E 같은 간단하면서도 강력한 단축키부터 외우기 시작해서 점점 Specific하게 단축어를 외우게 되며 생산성이 높아집니다. (이러다 보면 다른 툴은 답답해서 못 쓰게 됩니다ㅎㅎ)
나중에는 고이다 못해 모든 메뉴와 파일 탐색기 같은 부가적인 UI를 숨겨버리고 단축키로만 해결하는 사람을 보았습니다...
다른 JetBrains 제품을 쓰는 사람이랑 얘기하면서 자기만의 JetBrains Workflow(작업 흐름)을 공유하며 꿀팁을 흡수하는 것도 재밌습니다. (Visual Studio 쓸 때도 그렇긴 했지만) 이 제품군을 사용할 때 보다 더 생산성을 올리려면 어떻게 할까..? 기능 있을 것 같은데..? 이런 고민을 하는 것 같습니다.
가격이 부담될 수 있지만 JetBrains 제품은 학생이면 무료로 사용할 수 있습니다.
https://www.jetbrains.com/community/education/#students
비교
Rider가 기능적인 완성도가 높다고 했지만 사실 Visual Studio도 못 찾아서 그렇지 웬만한 고급 기능까지 다 있습니다.
뭔가 많이 부족하다거나 그런 것은 예전에도 느낀 적이 없었고 계속 개선이 되기 때문에 기능적으로 부족한 부분은 없을 것입니다.
Visual Studio 2022 for Mac이 나오면서 오히려 Visual Studio for Mac이 Rider에 비해 가벼워진 느낌을 줍니다.
마이크로소프트가 Mac이나 Linux 생태계도 신경을 많이 쓰고 있습니다.

.Net Desktop 업데이트를 멈추고 .Net Core와 통합된 .Net으로 업데이트를 하고 있습니다. 이런 것을 보면 개인적으로 Visual Studio를 계속 써도 될 것 같네요.
좀 더 빠릿빠릿한 걸 원하시면 Visual Studio를 써보시는 것은 어떤가요?
반면 JetBrains 제품에 익숙해진 분은 굳이 넘어갈 필요가 없을 겁니다.
정답은 없습니다. 처음이시면 둘 중에 그냥 마음에 드는 것을 골라보세용!
저는 요즘 DataGrip, IntelliJ, WebStorm, 등 JetBrains 제품을 많이 써서 Unity에 Rider를 붙여서 작업합니다.
도구 사용 Tip
Rider에서 컴파일된 IL 보기
C#을 공부하실 때 유용한 JetBrains의 기능 하나 소개해드리겠습니다. (물론 Visual Studio에도 있는 기능입니다)
👉 View Intermediate Language (IL)
컴파일된 IL 코드를 확인하는 기능입니다.
Shift를 두 번 연타하면 "Search Everywhere" 창이 나옵니다. 정확한 단축어를 모를 때 무엇이든 검색해서 실행할 수 있게 해 주는 만능 창입니다. ㅎㅎ

여기서 우리가 원하는 "il"을 쳐볼까요?

IL Viewer를 선택해서 엔터를 치면 우측에 IL Viewer가 열립니다.

Console.WriteLine으로 커서를 누르면 IL Viewer에서 해당 부분이 어떤 부분인지 하이라이팅 해줍니다.
이런 기능은 문법을 공부하며 내부적으로 정확하게 어떤 차이점이 있는지 파악하는데 도움이 됩니다.
Collection Initializer
예를 들어서, 그냥 Collection의 원소를 하나하나 추가하는 것이랑 Collection Initializer를 쓸 때의 차이점이 뭔가 싶으면 그냥 보면 됩니다.


for vs foreach
다음 코드를 봅시다.
1. for
for (int i = 0; i < uids.Count; i++)
{
Console.WriteLine(uids[i]);
}
2. foreach
foreach (var uid in uids)
{
Console.WriteLine(uid);
}
기능적으로 똑같아 보이는데 뭐가 차이가 있는지 봐볼까요?
1. for의 IL
// [17 18 - 17 27]
IL_002b: ldc.i4.0
IL_002c: stloc.1 // i
IL_002d: br.s IL_0042
// start of loop, entry point: IL_0042
// [18 13 - 18 14]
IL_002f: nop
// [19 17 - 19 44]
IL_0030: ldloc.0 // uids
IL_0031: ldloc.1 // i
IL_0032: callvirt instance !0/*int32*/ class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
IL_0037: call void [mscorlib]System.Console::WriteLine(int32)
IL_003c: nop
// [20 13 - 20 14]
IL_003d: nop
// [17 45 - 17 48]
IL_003e: ldloc.1 // i
IL_003f: ldc.i4.1
IL_0040: add
IL_0041: stloc.1 // i
// [17 29 - 17 43]
IL_0042: ldloc.1 // i
IL_0043: ldloc.0 // uids
IL_0044: callvirt instance int32 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Count()
IL_0049: clt
IL_004b: stloc.2 // V_2
IL_004c: ldloc.2 // V_2
IL_004d: brtrue.s IL_002f
// end of loop
2. foreach의 IL
// [24 13 - 24 20]
IL_0055: nop
// [24 33 - 24 37]
IL_0056: ldloc.0 // uids
IL_0057: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0/*int32*/> class [mscorlib]System.Collections.Generic.List`1<int32>::GetEnumerator()
IL_005c: stloc.3 // V_3
.try
{
IL_005d: br.s IL_0072
// start of loop, entry point: IL_0072
// [24 22 - 24 29]
IL_005f: ldloca.s V_3
IL_0061: call instance !0/*int32*/ valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::get_Current()
IL_0066: stloc.s uid
// [25 13 - 25 14]
IL_0068: nop
// [26 17 - 26 40]
IL_0069: ldloc.s uid
IL_006b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0070: nop
// [27 13 - 27 14]
IL_0071: nop
// [24 30 - 24 32]
IL_0072: ldloca.s V_3
IL_0074: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
IL_0079: brtrue.s IL_005f
// end of loop
IL_007b: leave.s IL_008c
} // end of .try
finally
{
IL_007d: ldloca.s V_3
IL_007f: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_0085: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_008a: nop
IL_008b: endfinally
} // end of finally
for는 list의 GetItem으로 원소를 가져옵니다.
foreach는 List를 List.enumerator로 받아서 순회합니다. enumerator의 get_Current로 현재 원소를 받고 다음 원소를 위해 MoveNext를 계속 호출하다가 finally에서 enumerator를 Dispose 하고 있습니다.
이처럼 같은 동작을 하는 코드이지만 전혀 다른 코드로 컴파일되는 것을 알 수 있습니다. 이런 궁금증이 드실 때 찾아보면 C#과 .Net을 이해하는데 도움이 되실 겁니다.
Low Level Code로 볼 수 있는 sharplab.io
비슷한 기능을 하는 사이트로는 C# 코드를 low level C#으로 변환해주는 사이트인 https://sharplab.io/가 있습니다.

책 추천

C# 공부를 시작하신다면 "시작하세요! C# 프로그래밍" 책을 추천드립니다.
처음에 C# 생태계를 설명하면서 버전별로 대표적인 문법을 소개해줍니다.
Windows에 의존적인 .Net Desktop이 아닌 .Net 기반으로 설명하시려고 노력한 것도 이 책의 장점 중의 하나입니다.
이 책에 대한 자세한 후기는 https://coding-groot.tistory.com/181를 참고해주세요!
구매 링크: https://wikibook.co.kr/cs10/
IDE의 여러 기능 사용해보면서 공부하면 더 많은 것을 볼 수 있고 소소한 재미를 느낄 수 있습니다.
공부할 때는 코드가 간단하고 사용할 기능도 별로 없지만 생산적인 IDE에 미리 익숙해진다 생각하면 이것저것 눌러보세요.
예시 코드를 막 리팩터링 기능을 사용해서 바꿔도 보고 컴파일되는 IL도 까보고 하세요!

<시작하세요! C# 프로그래밍> 서포터즈 활동은 제니퍼소프트(https://jennifersoft.com/)의 지원으로 진행됩니다.Fruit icons created by Freepik - Flaticon
댓글
이 글 공유하기
다른 글
-
[C# 8.0] Nullable Reference Type이란?
[C# 8.0] Nullable Reference Type이란?
2020.02.29 -
[C#] Nullable (Value Type)
[C#] Nullable (Value Type)
2020.02.26 -
[C#] 구조체(struct)
[C#] 구조체(struct)
2019.07.19 -
[C#] 배열 - 다차원 배열, 가변 배열
[C#] 배열 - 다차원 배열, 가변 배열
2019.07.17