class를 열심히 만드는 과정에서, C#에서 기본적으로 지원하는 연산자들에 기능을 부여할 수 있다!
vector 클래스를 만든다고 쳤을 때
+
가 vector의 합을 계산하도록 기능하게 만들 수 있다는 것.
기본적인 연산자 오버로드
public class Vector2
{
private int _x;
public int X { get; set; }
private int _y;
public int Y { get; set; }
public Vector2() { X = 0; Y = 0; }
public Vector2(int x, int y)
{
X = x;
Y = y;
}
public static Vector2 operator +(in Vector2 p1, in Vector2 p2)
{
return new Vector2(p1.X + p2.X, p1.Y + p2.Y);
}
}
operator 키워드를 이용하여 연산자 오버로드가 가능하다.
단항 연산자의 경우는 매개변수를 하나, 이항 연산자의 경우는 매개변수를 두 개 받는다.
이때 가장 앞에 오는 매개변수가 this
로 취급된다고 보면 된다.
오버로드 가능한 연산자들
1. 단항 연산자
true랑 false도 연산자인 건 처음 알았다.
public static bool operator true(LaunchStatus x) => x == Green || x == Yellow;
public static bool operator false(LaunchStatus x) => x == Red;
2. 이항 연산자
사칙연산 (+ 모듈러 연산), 비트 연산자 등이 모두 오버로딩이 가능하다.
3. 비교 연산자
비교 연산자는 반드시 반대되는 경우와 함께 짝으로 오버로드해줘야 함에 주의하자.
예를 들면 ==
를 오버로드할 때는
반대인 !=
를 같이 오버로드해줘야 한다.
<
와 >=
, >
와 <=
가 서로 짝이다.
오버로드할 수 없는 연산자
오버로드가 가능할 것 같은데 안되는 연산자들은, 다른 연산자가 오버로드 되면 따라 오버로드되는 방식이거나 다른 방법을 통해 할 수 있는 연산자들이다.
1. 조건부 논리 연산자
&&
및 ||
연산자는 &
및 |
연산자의 조건부 버전이다.
해당 조건부 논리 연산자를 오버로딩 할 수 없는 대신에,
그냥 &
및 |
연산자를 사용하면 된다.
&
및 |
연산자의 오버로딩이
&&
및 ||
연산자의 오버로딩으로 간주되는 경우도 있다.
해당 조건부 연산자가 어떻게 작동하는지를 알면 되는데,
&&
연산자는 T.false(x) ? x : T.&(x, y)
와 동일하게 작동한다.
이말은 즉슨?
false
연산자와 &
연산자가 오버로드 되면 &&
연산자도 오버로드된다는 말이다.
||
연산자는 마찬가지로 T.true(x) ? x : T.|(x, y)
와 동일하게 작동한다.
2. 인덱스 접근
배열 접근의 오버로딩은 인덱서라는 것을 통해 가능하다!
인덱서 (Indexer)
public class CodeInstanceContainer<T>
{
private T[] _data = new T[1000];
public T this[int i]
{
get
{
if (i < 0) throw new InvalidOperationException();
return _data[i];
}
set
{
while (i >= _data.Length) { increaseCapacity(Capacity << 1); }
_data[i] = value;
}
}
}
다음과 같은 방식으로 설정한 클래스의 인덱스 접근이 가능하다.
3. 변환 연산자 (캐스트)
암시적 변환은 implicit
,
명시적 변환은 explicit
키워드를 이용해서 가능하다.
implicit과 explicit
using System;
public readonly struct Digit
{
private readonly byte digit;
public Digit(byte digit)
{
if (digit > 9)
{
throw new ArgumentOutOfRangeException(nameof(digit), "Digit cannot be greater than nine.");
}
this.digit = digit;
}
public static implicit operator byte(Digit d) => d.digit;
public static explicit operator Digit(byte b) => new Digit(b);
public override string ToString() => $"{digit}";
}
public static class UserDefinedConversions
{
public static void Main()
{
var d = new Digit(7);
byte number = d;
Console.WriteLine(number); // output: 7
Digit digit = (Digit)number;
Console.WriteLine(digit); // output: 7
}
}
4. 이진 연산자
얘네는 사실 이해하기 그리 어렵진 않다.
짝이 되는 연산을 오버로드 해주면 이진 연산도 암시적으로 오버로드 되는 방식.
5. 불가능한 연산자
얘넨 그냥 안된다.
Uploaded by N2T
'개발 > Unity 내일배움캠프 TIL' 카테고리의 다른 글
C# Sort() 메서드 다루기 (0) | 2023.08.23 |
---|---|
C# DataTable 간단 사용법 (0) | 2023.08.22 |
코드 컨벤션 (0) | 2023.08.18 |
C# 생성자와 소멸자 그리고 가비지 컬렉터 (0) | 2023.08.17 |
C# 언어 기본 구조 (0) | 2023.08.14 |