ved_Rony
비동기 프로그래밍 - aync void를 지양하자 + (UniTaskVoid는?)
Programming/C# 2023. 12. 1. 15:36

제목에서 알수 있듯이, 비동기 프로그래밍을 짤 때, async void는 지양하는 것이 좋다. 그이유로는 에러 처리에 있어서 예상치 못한 문제를 야기 할수가 있어서 그렇다. 그렇다면, 이것이 대체 어떻게 우리 프로그램에 영향을 끼치는 것일까. 결론부터 보자면, async void의 execution이 에러를 일으키면 application은 crash된다. 예를 들어보겟다. BackGroundTask task = new(); Debug.Log("hello"); await task.RunTask(); Debug.Log("world"); public class BackGroundTask : Monobehaviour{ public async Task RunTask(){ await Task.Delay(1000);..

article thumbnail
C# - 부동 소수점 오차
Programming/C# 2023. 8. 20. 20:40

게임 개발을 하다보니, 플레이어의 위치, 타이밍, 걸리는 시간 등 정확한 계산을 요하는 일이 많이 생긴다. 특히나 플레이어간의 동기화를 고려하면, 사소한 오차로 클라이언트간의 소통오류로 이어질수가 있다. 그래서 float type을 사용할 때, 조금 더 주의를 해줘야한다. 바로 부동 소수점 오차, 즉, 플로팅 연산 오류가 생길수 있기 때문이다. 간단하게 개념만 이해한다면, float으로 계산을 하다보면, 가끔씩 소수점 하위 부분에서 각 하드웨어(cpu)의 연산 방식, 성능 등에 따라서, 오류가 생기기도 하는 데, 예를 들어, (float type) * (float type) 의 결과 값이 10f가 나와야 한다면, 9.999999999f가 나온다는 것이다. 왜 이런 일이 벌어지는 것일까? 모든 십진수들이 ..

article thumbnail
c++ -> c#인터프리터 정리
Programming/C# 2023. 7. 3. 19:20

c++ 아두이노 언어를 c#으로 변환해주는 인터프리터 이 인터프리터를 가지고 c++를 c#으로 전환해주고, 유니티에서 가상 시뮬레이션을 돌려준다. 먼저, runcode 함수를 실행 → 이때 lexer와 parser를 생성해주는 데 lexer에 전체 코드를 넣어준다. lexer와 parser의 역할은 뒷 내용을 보다보면 이해가 가겠지만, lexer는 코드의 string byte를 token으로 인식하게 해주고, parser는 이 token으로 해석을 시작한다. 이과정에서 AST(추상구문트리)의 노드 구조를 형성하고, 이후에 evaluater에서 이러한 트리구조를 실행해준다. private static async UniTask RunCode(string code) { var lexer = new Lexer(..

Effective C# - item 1 ~ 10
Programming/C# 2022. 10. 3. 15:29

1. 지역변수를 선언 할때는 var가 더 낫다. 그렇다면 var를 무작정 사용하면 타입 선정하는 데 걸리는 시간이 늘어나 컴파일 타임에 악영향을 주는게 아닐까? - 암시적으로 변수를 선언한 코드가 더 잘 읽힌다. ​변수의 의미 자체에 더 집중할 수 있다. 하지만 변수의 타입 정보가 필요할 때, 정확하게 유추할 수 있도록 코드를 짜는 편이 좋다. 예를 들어, JSON object의 경우 타입 자체에 대한 정보가 아닌 그에 담긴 데이터가 중요한경우가 많으므로 var로 선언 해주는 것이 좋다. 또한, 내장 숫자 타입을 리턴하는 메서드의 경우 메서드 이름에 숫자 타입이 적혀있지 않다면 해당 메서드가 출력하는 리턴값의 타입이 어떤 것인지 확신할 수 없다. 따라서 내장 숫자 타입 같은 경우엔 var보다는 명시적으로..

Effective C# - 제네릭의 활용) 타입 매겨변수가 IDispoable을 구현할 경우를 대비해 제네릭을 만든다.
Programming/C# 2022. 9. 11. 14:07

제네릭의 제약 조건은 크게 두가지 역할을 한다고 볼수 있다. - 런타임 오류를 컴파일 오류로 발생하도록 바꿔준다. - 타입매개변수를 규정해 사용자에게 도움을 준다. 이때, 요구작어보이에 그 타입이 어떤 작업을 하는 지 기능이 있는 지, 신경을 쓰지 않지만, IDisposable을 구현할 경우 특별한 작업이 추가적으로 필요하다. 제네릭 메서드 내에서 타입 매개변수로 주어지는 타입을 이용하여 인스턴스를 생성할 경우 -> 타입 매개변수에서 IDisposable을 구현하고 있을 때 만약, 매개변수 타입의 인스턴스를 생성할 때, (T 변수명 = new)일경우 이타입의 메소드를 불러올 때, IDisposable을 체크해주지 않는다면, 리소스 누수가 일어날수있다고 한다. (using 변수명 as IDisposable..

Effective C# - 제네릭의 활용) 런타임에 타입을 확인하여 최적의 알고리즘을 사용하자.
Programming/C# 2022. 9. 11. 13:37

제네릭을 사용하게 되면, 코드가 간결화 되지만, 타입을 제네릭화하면 그타입이 주는 특성을 잃어 버리게 된다. 그 특징을 활용하여 알고리즘을 최적화하는 게 좋다. => 타입 매개변수로 지정될 가능성이 있는 친구들에 대해 특화된 기능을 최대한 활용해 제네릭을 만들어 준다. 예시로, IList가 타입 매개변수로 들어오게 되면 IList일 경우 이런이런 기능을 쓰겠다고 해준다. 이렇게 함으로서 코드의 재사용성이 높아지고, 개별 타입에 대해 최적화된다. 실 예제를 자성할 필요가 있을 듯 하다..

Effective C#-제네릭 활용: 필요한 제약 조건만 설정 +) 제네릭?
Programming/C# 2022. 9. 2. 17:55

C#의 제네릭은 타입을 특정하지 않고 데이터 타입 패러미터를 받아서 원하는 방식으로 처리를 해주는 방식이다. ex) public static void test (T left, T right) where T ~ 이렇게 생긴 친구들. T가 데이터 타입 패러미터라고 할수 있다. - 주로 컬렉션과 함께 사용해야 유용하다고 하는 의견들이 많다고 한다. 하지만, 인터페이스, 이벤트 핸들러, 공통 알고리즘에도 유용하다. - 제네릭 방식 -> 장점: 코드 짧아진다, 데이터가 준다, 박싱, 언박싱을 피할수 있다. 단점: 메모리 풋프린트가 많이 든다. (서로 다른 타입이 제네릭을 이용해 선언된다면, 서로 다른 머신 코드가 계속 파생되기 때문) List s, List d.. => 제네릭이 아닐 경우 하나의 머신코드 but,..

article thumbnail
Effective C# - 캐스트보다 is, as를 사용하자
Programming/C# 2022. 8. 29. 16:03

C#은 정적타이핑, 즉 데이터 타입을 미리 선언해줘서 컴퓨터의 부담을 덜어줄수 있다고 한다. 타입 불일치가 발생하더라도 컴파일러가 이를 확인해준다. object타입의 인자를 취하는 경우도 있는데, 이때 클래스나 혹은 인터페이스로 형변환하여 사용한다. 이렇게, 형변환의 사용이유들이 있는데, 그렇다면, c#에서는 형변환을 어떻게 할까 크게 두가지가 있다. 캐스팅과 is이다. 형변화을 할때 is를 사용하여 방어적인 코드, 쉽게 말해 null체크 같은 예외적인 상황을 대비 할수 있게 해준다. 캐스팅을 사용한다면, try-catch문으로 exception체크를 해줘야하는데, 가독성이 떨어진다. 반면, as를 사용할경우 형변환 실패시, null이 반환되므로 null체크만 해주면 되는데, 가독성 면에서 유리하다. a..

검색 태그