[.Net C# 설명서] 읽고 정리하기
본 글은 공부하며 작성하였습니다. 정보를 얻으실 때 사실과 다르거나 부정확한 정보가 들어있을 수도 있습니다.
내용 출처
https://docs.microsoft.com/ko-kr/dotnet/csharp/tour-of-csharp/
최근에 기초를 더 탄탄하게 다져야 한다고 느껴서, C# 라이브러리를 읽고 정리해보기로 했다. 이전 글과 마찬가지로, 전체 내용보다는 새롭게 배웠거나 필요성을 느낀 내용들을 정리해보려 한다.
부호 있는 정수와 부호 없는 정수
부호 있는 정수 : sbyte, short, int, long
부호 없는 정수 : byte, ushort, uint, ulong
실구현에서는 오버플로우나 연산 관련 오류가 발생할 일이 없어 int만 사용했으나, 코딩 테스트를 겪으면서 깨알같은 중요성을 느꼈다. 특히 해커랭크.
막상 필요하다고 여기고 나니까 어딘가에 쓸 일이 있을 것 같기도 하고 그렇다.
튜플
(double, int) t1 = (4.5, 3);
print(t1.Item1);
(double Sum, int Count) t2 = (4.5, 3);
print($"Sum of {t2.Count} elements is {t2.Sum}");
튜플 또한 클래스나 구조체를 사용하지, 굳이 쓸 이유가 없다고 생각했었는데, 지역 변수로 사용한다면 클린 코드에 도움이 될 것 같았다. 무울론 잘 안 쓸 것 같다.
박싱/언박싱
int i = 123;
object o = i; //Boxing
int j = (int)o; //Unboxing
값 형식이 object 참조에 할당되면 박싱이 일어난다. o는 i를 담고 있지만, 참조 형태로 담게 된다.
라벨도 붙여져있지 않은 상자에 '과자'들을 넣은 게 박싱이라고 생각하면 된다.
언박싱은 이 상자에 '과자'들이 들어 있었는데...? 하면서 꺼내려고 시도하는 것이다. ...비유가 좀 그렇긴 한데.
아무튼, int는 값 형식이고, object는 참조 형식이다. 결론적으로 박싱과 언박싱은 값 <=> 참조를 의미하는 것이다.
비용이 비싸기 때문에, 이러한 현상이 발생하지 않게끔 조심해야 한다.
예전 NDC 자료에서 Enum 타입을 키로 사용하면 박싱/언박싱이 발생하기 때문에 주의해야 한다, 라는 말이 있었는데. 닷넷 4.0이 업데이트 되면서 옛말이 되었다. 굳이 레거시인 말을 쓰는 이유는 혹시나 닷넷 2.0을 쓸 수도 있어서...?
결론은 ArrayList 같은 복합 자료형은 웬만하면 쓰지 말자.
인터페이스 형식으로 암시적 변환하기
클래스 또는 구조체가 특정한 인터페이스를 구현하고 있으면, 해당 인터페이스 형식으로 암시적 변환이 가능하다.
EditBox editbox = new EditBox();
IControl control = editbox;
IDataBound dataBound = editbox;
이는 생각해보면 매우 익숙한데, LinQ를 사용할 때 List 타입을 IEnumerable 타입으로 변환하여 연산하는 것을 떠올려보면 된다.
Enum의 Flag 연산
[Flags]
public enum Days
{
None = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64,
Weekend = Saturday | Sunday
}
Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;
Console.WriteLine(meetingDays);
// Output:
// Monday, Wednesday, Friday
Days workingFromHomeDays = Days.Thursday | Days.Friday;
Console.WriteLine($"Join a meeting by phone on {meetingDays & workingFromHomeDays}");
// Output:
// Join a meeting by phone on Friday
Flag와 비트 연산을 사용하면 선택을 조합할 수 있다. 이 때, Flags Attribute를 선언해야 하고, 연결된 값은 제곱이어야 한다.
이진수로 변환해보면 알기 쉬운데, Weekend는 0100000과 1000000을 OR연산하여 1100000으로 만든 것이다.
그러므로 아래쪽 코드는 0010101 | 0011000 = 001000이므로, Friday인 것이다.
...switch로 enum의 공통 카테고리를 분류했던 과거의 나를 공격하자.
아래쪽 코드의 meetingDays를 출력했을 때 Monday, Wednesday, Friday가 나오는 건 좀 신기하군.
Nullable 유형
int? optionalInt = default;
int Int = default;
//Null
//0
자료형에서 null을 허용하게 만들고 싶으면 물음표를 붙이면 된다. 우와아아악!!!
코딩 테스트에서 잘 써먹었다.
접근 제한자
- public
- private
- protected
- internal : 액세스가 현재 어셈블리로 제한된다. dll을 떠올려보면 왜 사용하는지 이해하기 쉽다.
- protected internal : 두 제한자에 OR을 건 것. protected이거나 internal 상황에서만 참조 가능하다.
- private protected : internal이고 protected여야만 참조 가능하다. 이름 왜 이렇게 지었죠?
속성도 가상(virtual)일 수 있다
public class temp1
{
protected int _test;
public virtual int Test
{
get => _test;
set => _test = value;
}
}
public class temp2 : temp1
{
public override int Test
{
get => 1;
set => base.Test = value;
}
}
이렇게 만들고, print(new temp2().Test)를 하면 1이 나온다. 어떻게 보면 당연한 것인데 당연하게 생각하지 않았음.
인덱서
class SampleCollection<T>
{
private T[] arr = new T[100];
public T this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
예시는 제네릭이지만, 어떤 자료형이든 상관없다.
해당 클래스를 인덱스 형태로 접근 가능하게 만들어준다. 커스텀 클래스를 배열이나 리스트 형태로 만들 수 있는 것.
Length나 Count 속성이 없기에, 필요하면 직접 만들어줘야 한다. 커스텀 클래스니까.
StringBuilder 좀 써라
String은 변경할 수 없는 형식이다. 그러니까 만들 때마다 인스턴스가 생성된다고!
"안녕" + "하세요" + "?" 는 3개의 쓰레기 인스턴스를 만드니까, 부하가 발생한다.
StringBuilder는 Append를 할 때 인스턴스를 생성시키지 않는다. 그러니까 쓰라고!
나중에 바꿔야지 하지 말고 바로 쓰라고! 나에게 격렬하게 외친다...
'프로그래밍 > C#' 카테고리의 다른 글
C# 구조체 : 기본 매개변수를 사용한 생성자는 호출되지 않을 수도 있다 (0) | 2022.07.10 |
---|---|
Enum.ToString 최적화하기 (0) | 2022.02.25 |
[C# 코딩의 기술]에서 얻은 지식들 (0) | 2021.09.24 |
C# 연산자 오버로딩 : ==, Equals에서 null값 판단하기 (0) | 2021.03.24 |
LINQ Method 정리 (1) | 2020.05.06 |
댓글
이 글 공유하기
다른 글
-
C# 구조체 : 기본 매개변수를 사용한 생성자는 호출되지 않을 수도 있다
C# 구조체 : 기본 매개변수를 사용한 생성자는 호출되지 않을 수도 있다
2022.07.10 -
Enum.ToString 최적화하기
Enum.ToString 최적화하기
2022.02.25 -
[C# 코딩의 기술]에서 얻은 지식들
[C# 코딩의 기술]에서 얻은 지식들
2021.09.24 -
C# 연산자 오버로딩 : ==, Equals에서 null값 판단하기
C# 연산자 오버로딩 : ==, Equals에서 null값 판단하기
2021.03.24