C#

C# - 2

재밌는게임~ 2024. 5. 19. 19:19

C# 에서 의외로 넘어가기 쉬운 것에 대해서 간단 정리 !!

 

- Namespace : 성격이나 하는 일을 묶는 역할

- CLR (Common Languange Runtime) : C#으로 만든 프로그램이 실행되는 환경

 

C++ --------

C#   --------    IL (중간언어) ---- OS ---> 실행

Python  ---

 

컴파일러는 다양한 언어에서 중간언어로 된 실행파일을 생성하고, CLR은 다시 OS가 읽을 수 있는 네이티브 코드로 컴파일 후 실행하는 방식으로 동작한다.

 

- 데이터 타입 

  - 값 타입 - 스택 공간에 값이 저장되어 있음

  - 참조 타입 - 스택 공간에 주소가 저장되어 있음, 주소는 힙 공간을 가리키며, 힙 공간에는 해당 값이 들어있음

 

! 어떤 어떤 게 값타입이고 참조타입인지는

C# (tistory.com)  <-- 여기 나와있음

 

- 모든 데이터 타입의 base 는 Object Type 이다.

- Decimal은 29자리 까지 표현할 수 있는 소수 형식 이며

// Decimal de = 3.1534413215151m ; 처럼 마지막에 m을 붙여준다.

 

- 박싱, 언박싱

박싱 : 값 타입을 참조 타입으로 포장해서 옮긴다. (스택 -> 힙)

언박싱 : 참조 타입을 값 타입으로 포장을 풀어서 옮긴다.  (힙 -> 스택)

//박싱, 언박싱은 속도를 느리게 하는 주범이므로 많이 일어나면 좋지않다...

 

- 변수, 상수

변수 : int a = 0; //a는 변수이다. //즉 변할 수 있다라는 뜻

상수 : const int a = 0; //a는 상수이다.  //const로 인해 변하지 않는 값이 되어버림

 

- var : C#은 강한형식검사를 하지만 var 키워드를 사용하면 약한형식검사를 하게 된다. 하지만 var는 반드시 선언과 동시에 초기화를 해줘야하고, 지역변수만 가능하다.

 

- 공용형식시스템 : 다양한 프로그래밍 언어를 호환하기 위해 만든 표준 형식 시스템 ( .NET 언어들이라면 무조건 따라야한다.)

 

- 연산자 우선순위가 있다. (+-/* 처럼 다양한 연산자가 있다. 그래서 연산을 할때 어떤 것을 먼저 검사하는지 확인하기 때문에 한번 봐두면 좋다.)

 

- 조건문 사용 (조건문이 여러개가 생길경우 중첩하기 보단 아닌것을 리턴하는 코드가 더 깔끔하다.)

 

- 참조에 의한 매개변수 전달

ref : 함수호출 시 참조 매개변수를 넣기 때문에 swap함수가 끝나도 값이 변한다. //ref 함수를 안넣으면 지역변수는 해당함수가 종료되면 그대로 사라진다.)

void swap(ref int a, ref int b){ };

 

out : ref와 비슷하지만 해당 메소드에서 결과를 저장안해도 컴파일러가 경고하지 않는다. (출력 전용 매개변수)

 

- 가변길이 매개변수 (Params)  : 매개변수의 갯수가 정해져있으면 오버로딩 아니면 가변길이 매개변수를 사용

void swap(params int[] a){};

 

- 선택적 매개변수 : 매개변수에 기본값을 정해놓는다. 

void swap(string name, int age = 0, string height = "180") //단! 기본값은 매개변수들 중에 뒤쪽에 배치한다.

 

- C# 클래스에서 선언한 변수는 "필드" 라고 한다.

 

- 생성자, 소멸자 

말 그대로 생성할 때 호출 소멸할 때 호출하지만 C#은 CLR 안에 가비지 컬렉터로 인해서 소멸자는 잘 사용하지 않는다.

생성자는 베이스 -> 파생 클래스 순서대로 호출 

소멸자는 파생 -> 베이스 클래스 순서대로 호출

 

- 정적 필드 메소드

Static은 메소드나 필드가 클래스의 인스턴스가 아닌 클래스 자체에 소속되도록 지정되는 한정자이다.

 

- 객체 복사

얕은 복사 : 힙에 서로 다른 주소가 할당되어 있기 때문에 복사한 객체만 변함

깊은 복사 : 같은 주소를 참조하기 때문에 서로 다른 1개를 변경시켜도 전체가 변함 

 

- public, protected, private, internal

public, protected, private에 대해서는 잘알지만 internal은 모르거나 까먹었을 수 있다. 

Internal : 같은 어셈블리에 있는 것에서는 public 형태로 다른 어셈블리에 있는 것은 private 과 같은 접근 수준을 가진다.

 

- Sealed 키워드 

상속봉인 키워드 이며, 클래스, 메소드에서 사용한다.

 

- is , as ( C#의 캐스팅 연산자로 객체를 캐스팅 할때 사용)

  • 기본적으로 상속관계의 클래스간 하향캐스팅을 할 때 사용된다.

is : 객체가 해당 형식에 해당하는지를 검사하여 그 결과를 bool 값으로 반환

예)

  Animal animal = new Dog();

  Dog dog;

  if(animal is dog){

      dog = (Dog)animal;

  }

as : 형식 변환 연산자와 같은 역할 다만 형변환 연산자가 변환에 실패하는 경우 예외를 내보내지 않고 객체 참조를 null로 만듬

예)

  Animal animal = new Dog();

  Dog dog = animal as Dog;

  if(dog != null){    <------------// 변환에 실패 했다면 null 처리가 되어있을 것이다.

       dog.ddd();

  }

 

결국 위에 말을 종합하여 보았을 때 

'강제 형 변환의 경우 형 변환이 수행될 수도 있고, 그렇지 않을 수도 있지만 as 키워드를 사용하여

형 변환이 100% 수행될 것이라고 판단할 수 있다.'

 

 

- 중첩 클래스

클래스 외부에 공개하고 싶지 않는 형식을 만들 때와 현재의 클래스 일부분처럼 사용하려 할 때 사용

 

- 분할 클래스 ( Partial )

클래스 구현이 길어지면 여러개의 나눠서 정의할 수 있게 해주는 키워드 (사용 시 가독성이 좋아짐)

 

- 구조체와 클래스 비교

class                               /                 struct

참조형식                         /                값형식

얕은복사                         /              깊은복사

new연산자 또는 생성자 필요 / 선언만으로도 생성

 

- 추상클래스와 인터페이스 차이점

1. 추상클래스는 구현을 가질 수 있다.

2. 인터페이스는 다중상속이 가능하다. (다중상속이 가능하지만 다이아몬드 문제로 인해서 조심해야한다.)

 

- 프로퍼티

은닉성이 중요한 프로그래밍에 필드를 보호해주고, 컨트롤 할 수 있게 만듬

 

- 일반화 프로그래밍

특수한 개념으로 부터 공통된 개념을 묶는 것을 일반화라고 한다. (Generalization)

 

-형식 매개변수 제약(조건) 시키기

Class myList<T> where T : class  : 참조 타입만 가능 

                                            struct : 값 타입만 가능 

 

이처럼 다양한 조건을 줄 수 있다. 하나의 클래스만으로 지정할 수 도 있다.

 

- 예외처리

try{ } catch() {} 문으로 예외처리가 가능하며 try에서 생긴 예외를 catch (Exception e) 에서 받아서 처리

여러 예외 키워드가 있지만 모든 예외 키워드는 Exception 가 base 이기 때문에 Exception 로 처리가 가능하다.

finaly{}; : catch문 밑에 작성하며, 예외가 생겨도 무조건 실행되는 녀석이다.

 

- 델리게이트 (대리자)

다양한 방식을 알아보자

 

사용방법 1

Delegate callback;  - 선언

callback = new Delegate(함수);  - 대입

Console.WriteLine(callback(함수)) - 사용

 

사용방법 2

Delegate int callback(int a, int b); - 선언

int AC(int a, int b){ } - 함수선언

void Sort(callback cb){ } - 매개변수로 델리게이트 넘기는 함수 선언

 

Sort (new callback(AC));  - 사용

 

사용방법 (무명함수(익명 메소드))

Delegate int callback(int a, int b); - 선언

callback cals;

cals = Delegate (int a, int b) { return a + b; } - 대입

 

clas(3,4); - 사용

 

- event 도 비슷하지만 델리게이트와 다른점은 public 으로 되어있어도 클래스 외부에서 사용못함

 

- 람다식

cals = Delegate (int a, int b) { return a + b; } 이 코드가 람다식으로는 cals = (a,b) => a+b; 로 가능하다.

 

- func , action

func : 반환이 있는 델리게이트 (<>안 마지막 인자가 반환 형식)

action : 반환이 없는 델리게이트

 

- Linq

데이터 관리를 편하게 해준다.

예) 

var profiles = from profile in profileList

                      where profile.height < 175

                      orderby profile.height

                      select profile

이런 식으로 동작 (자세한 건 검색하면 많은 정보가 있다, join, groupby 등등...)

 

- 리플렉션  

객체의 형식 정보를 들여다보는 기능 (형식이름, 프로퍼티목록, 메소드목록, 필드, 이벤트 목록까지)

 

사용방법

int a = 0;

Type type = a.GetType();

FieldInfo[] fields = type.GetField();  <-- 여러 메소드가 있다. 필요한거 골라 쓰시면 됨

 

하지만 Object.GetType()은 객체의 인스턴스가 있어야 호출이 가능하지만 typeof , Type.GetType()은 없어도 사용가능

 

- 어트리뷰트

코드에 대한 부가정보를 기록하고 읽을 수 있는 기능

 

[Obsolete("이건 꼭 알아야한다,")] 이렇게 클래스, 메소드 위에 Obsolete 키워드를 많이 사용하고 사용자 정의로도 가능

class move(){}

 

- dynamic (데이터 타입)

오류 코드에도 컴파일 시 실행할 때 뒤로 미루는 타입이다.

 

- async , await

비동기 방식 실행 키워드

예)

async void A(){

        2)

       await Task.Run(async() => {

                       ~~

                       3)

                       ~~

      }

}

 

void B(){

      1)

      A();

      4)

}

 

설명 : B함수에서 1)이 실행 되며 -> A함수를 호출하면서 2) 실행 await을 만나는 순간 3) 4)가 동시에 실행되는 형태이다.

 

 

여기까지 C#을 알아볼때 쉽게 지나쳐갈 수 있는 것들을 적어보았다. 빠트린것도 많지만 나중에 다시 정리해보겠다...

728x90