C# - 2
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#을 알아볼때 쉽게 지나쳐갈 수 있는 것들을 적어보았다. 빠트린것도 많지만 나중에 다시 정리해보겠다...