소멸자

가비지 컬렉터가 돌기전에 실행된다.


nameof연산자

임의의 기호(형식, 멤버, 변수 등)의 이름에 해당하는 문자열을 돌려준다.

출력 "count"

그냥 해당 문자열을 직접 지정하는 것에 비한 이 연산자의 장점은 정적 형식 점검이 일어난다. 참조 같은 형식으로 해당 기호의 이름을 바꾸면 그에 대한 모든 참조의 이름도 바뀐다. (컴파일 시점에 평가되며 런타임의 영향을 주지 않는다.)

출력 결과

nameof언제사용할까? 

1. ToString보다 빠르다.

enum MyEnum { ... FooBar = 7 ... }

Console.WriteLine(MyEnum.FooBar.ToString());

> "FooBar"

ToString()은 런타임에 실행되고 nameof는 컴파일 시 실행되기때문에 상대적으로 ToString()이 느리다.

Console.WriteLine(nameof(MyEnum.FooBar))

> "FooBar"

2. 예외상황이 최신화 상태로 유지된다.

public string DoSomething(string input) 
{
    if(input == null) 
    {
        throw new ArgumentNullException(nameof(input));
    }
    ...

input매개 변수의 이름이 바뀌어도 속성이나 파라미터의 이름을 얻기 때문에 

 

https://stackoverflow.com/questions/31695900/what-is-the-purpose-of-nameof

객체 초기치 대 선택적 매개변수

읽기전용으로 만들기에는 좋음 하지만 각 선택적 매개변수의 기본값이 호출 지점에 들어박힌다는 단점

 Bunny bunny = new Bunny("Rabit", true, false); 

(매개변수 bool변수의 기본값은 false)

 

식 본문 속성

C# 읽기전용 필드를 이런식으로 사용이 가능하다.

위 그림은 읽기전용 필드로 설정되어 '2'을 넣을 수 없다.

 

인덱서의 구현

이렇게도 접근자를 제한해서 자신클래스 아니면 접근하지 set 못하게 할 수 있다.

 

정적생성자

발생조건 : 1. 형식을 인스턴스화한다. 2. 형식의 정적 멤버에 접근한다.

초기화 순서 : 정적 생성자가 호출되기 전에 실행된다. 형식에 정적 생성자가 없으면 정적 필드들은 해당 형식이 쓰이기 직전에 초기화 될 수도 있고, 런타임의 판단에 따라서는 그보다 전의 임의의 시점에 초기화될 수도 있다.

예제2개를 보고 결과값을 예상해보자

정적필드들은 선언된 순서대로 초기화된다. X는 0으로 Y는 3으로 초기화된다.

만약 순서를 바꾼다면? 모두 3으로 초기화 된다.

결과는 0과 3을 출력한다.

namespace안에 using 지시자를 중첩할 수 있다. 한 이름 공간 선언 안에서 using 지시자로 도입한 이름들은 그 이름공간 선언

global

식 본문 메서드

결과는 4

 

생성자의 중복적재

공통 언어 런타임 CLR

 마이크로 소프트 이니셔티브에서 제공하는 가상 머신의 구성요소이다. 프로그램 코드를 위한 실행 환경을 정의하는 마이크로소프트의 공통 언어 기반(CLI)표준의 기능이다. C#이나 VB닷넷과 같은 언어로 프로그래밍하며, 해당 언어의 컴파일러가 소스 코드를 공통 중간 언어(IL) 코드로 변환한다. 

CLR은 관리되는 코드(managed code)를 실행하기 위한 런타임이다. C#은 여러 관리되는 언어중 하나인데, 관리되는 언어로 작성한 소스코드를 컴파일 하면 관리되는 코드가 생성된다. 관리되는 코드를 실행 파일또는 라이브러리(.dll)형태로 만들고 그것을 형식 정보, 즉 메타자료와 함께 하나의 패키지로 묶은 것을 어셈블리라고 한다. 어셈블리를 적재 할 때 CLR은 IL코드를 해당 컴퓨터(x86 등) 고유의 기계어 코드로 변환한다. 이러한 변환을  담당하는 것이 CLR의 JIT(Just - in - time)컴파일러이다. 어셈블리는 원래의 원본 언어의 구성을 거의 그대로 유지하기 때문에, 코드를 조사하기 쉽고 심지어 동적으로 생성하기도 쉽다.

위캐백과

 

 

1.이니셔티브 : 우선권, 주도권, 스스로 상황 판단을하고, 남들이 움직이기 전에 먼저 움직일 수 있는 능력

2.CLI : Command-Line user Interface또는 Character User Interface

같은 클래스로 인스턴스를 new로 생성하게 되면  

1번을 제외하고 2~4번은 false

참조형 변수의 주소값을 비교하는 object.ReferenceEquals

즉, 관리 힙에 할당된 객체의 참조 주소 값을 비교해 '같음 여부'를 판단하기 때문에, object.ReferenceEquals '값 형식'의 인스턴스에 사용해서는 안됨

값형식을 넣으면 오류는 안나지만 false를 반환

object.ReferenceEquals의 값을 넣게되면 매개변수타입이 object형식이라 박싱과정이 거친다. 그러면 힙메모리에 값이 할당되게 된다. 결국 스택에 있는 서로다른 주소값이 생기기 떄문에 항상 false를 반환하게된다.

 

 

 

abstract :

상속 제한 : sealed키워드와 반대로 무조건 상속해서 쓰라는 의미 

메서드 오버 라이딩 제한 : 이 메서드는 반드시 오브 라이딩해달라는 의미

 

as :

객체를 캐스팅 할 때 사용되는 연산자로, 캐스팅에 성공하면 캐스트 결과를 리턴하고 실패하면 null을 리턴

 

is :

캐스팅이 가능하면 true, 아니면 false를 리턴

 

base :

해당 키워드를 사용하는 부모 클래스를 가리키는 것

 

const :

상수 필드 또는 지역 상수를 선언할 때 사용한다. 변수가 아니며, 한번 값이 할당되면 이후 변경이 불가능

 

readonly :

성수를 선언할 때 사용, 선언 시 선언할 때 값을 할당하지 않아도 됨, const와 다르게 생성자에서 한번 더 값 변경이 가능하다.

 

continue :

반복문에서 continue키워드 선언 이후 부분은 넘기고 다음 반복문부터 시작하도록 한다.

 

decimal :

고정 소수점 방식이며 연산 속도가 빠르고 수의 정확성이 높은 데신 큰 수를 저장할 때 메모리를 많이 먹게 된다. 16byte

 

double:

부동소수점 방식이며 decimal보다 정확성은 떨어지지만 작은 메모리 공간에 큰 소수를 저장이 가능하다.

 

event :

public이어도 자신이 선언되어 있는 클래스의 외부에서는 호출이 불가능, 객체의 상태 변화나 사건의 발생을 알리는 용도로 사용

 

delegate:

메서드 참조를 포함하고 있는 영역

 

size of :

지정된 형식의 변수에서 사용하는 바이트 수를 반환한다.

 

 디자인 패턴 

싱글톤 패턴

같은 인스턴스를 여러 개 만들지 않고, 최초 한번만 메모리를 할당하고 그 메모리에 인스턴스를 만들어서 사용하는 패턴이다. 어디서든지 접근하기 쉽다.

 

구현방법

가장 기본적인 싱글턴 구현 방법이다. 인스턴스를 요청하기 전까지는 객체를 생성하지 않는다.

늦은 초기화(Lazy initialization) : 멀티스레드 환경에서는 동시에 Instance을 호출하게 되면 둘 이상 객체가 만들어질 위험이 있다.

 

정적 초기화

이른 초기화(Eager initialization) 

로딩 때 생성되므로 스레딩에 안전한 대신 미리 생성하므로 안 쓰는 경우에 메모리 낭비가 될 수 있음

 

멀티스레드에서 교착상태를 피하기 위한 싱글턴

교착상태를 피하기 위해 이중 검사 잠금

lock키워드 설명 : http://www.csharpstudy.com/Threads/lock.aspx

 

싱글턴 문제점

개방 폐쇄 원칙(OCP)을 위배될 수 있다. (객체 지향 설계 원칙)

커플링이 심해질 수 있음 => 한 곳에서 변경이 다른 부분에 영향을 미치게 될 확률이 커짐

 

학습 참고 사이트

 

제어구조


if

String.valid? string인지 체크

 


unless

is_intege 숫자인지 체크

 


case

여러 패턴에 대해 매치해야 한다면 case를 이용

일치하는 패턴이 없는 경우 에러발생

'_'는 "그 외의 모든 것"에 매치되는 else처럼 생각하면 된다. (case구문에서 '_'이 없다면 일치하는 패턴이 없을 때 오류 발생)

 

'_'사용

 

case는 패턴 매칭에 의존하기 때문에 같은 규칙과 제약이 모두 적용된다. 기존의 변수에 매치하고자 한다면 핀연산자를 사용해야한다.

 

when으로 점검기능이있다. x > 0 크면 "Will match"

 


Cond

값이 아닌 조건식에 매치해야 할 때 사용 (else if 기능)

Cond문 마찬가지로 예외처리가 없으면 에러를 발생하는데, true조건식으로 처리해준다.

 


with

중첩된 case구문이 쓰일만한 곳이나 깔끔하게 파이프 연산을 할 수 없는 상황에서 유용하다.

'<-'은 오른쪽을 왼쪽과 비교하기 위해 패턴매칭을 사용

매치 실패한 경우

 

'프로그래밍언어 > Elixir' 카테고리의 다른 글

Elixir) 예제 연습_패턴 매칭  (0) 2019.08.22
(Elixir)로 JSON API 서버 만들기  (0) 2019.08.21
Elixir) 예제 연습 Enum  (0) 2019.08.21

패턴 매칭은 Elixir의 강력한 기능. 간단한 값, 자료 구조, 심지어는 함수까지도 매치시킬 수 있음

 

 

상수 매칭

 

컬렉션 매칭

1. 리스트

2. 튜플

 

핀 연산자

매치 연산자의 좌변에 변수가 포함되어 있을 때에는 값의 대입이 일어납니다. 하지만 경우에 따라서는, 뱐수에 새로운값이 대입되는 것을 원치 않을 수 있다. 이러한 상황에서는 핀 연산자^를 사용해야한다.

함수의 절에 핀연산 적용

 

어떤 임의의 URL을 입력하면 JSON형식의 텍스트를 반환하는 API서버

 

프로젝트 생성

cmd터미널에서 mix new 명령으로 새프로젝트를 생성한다.

그러면 아래 처럼 내컴퓨터의 생성한 프로젝트 이름으로 폴더가 생긴다.

 

생성한 디렉터리로 들어가서 구조를 확인해봤다.

 

 

의존 라이브러리 추가하기

mix.exe파일에 끝에있는 deps함수를 수정한다. 프로젝트에서 의존하는 라이브러리를 추가하는 부분이다.

   나는 {:plug_cowboy , " ~> 1.0 " }, 이걸로 종속성을 수정해야 되었다.

 

밑에 mix명령어를 통해 로컬프로젝트 속으로 import시킨다.

 

 

다음은 application함수를 아래와 같이 수정하자

이 프로젝트에서사용될 어플리케이션들을 선언하는 부분이다.

 

아래와 같이 입력하면 iex 입력으로 바뀐다.

이 상태에서 앞서 mix설정에서 추가한 웹서버인 CowboyHTTP서버를 실행하자

아래 명령문을 통해 실행한다.

웹브라우저를 통한 확인

잘나오면 MyApp모듈이 Cowboy웹서버와 연동이 된것이다. 

 

 

API 서버 구현

URL/users/tom을 호출하면 사용자 프로필 정보를 JSON형식으로 출력하는 간단한 API서버가 된다.

my_app.ex파일 수정

get " /users/:name" do부분에서 URL맵핑을 통해 웹요청을 처리하고,

마지막 match _do부분은 이도저도 아닌 나머지 요청에 대한 처리(catch-all)루틴이다.

'|>'sms Elixir의 파이프 연산자이다.

 

명령행에서 API 서버 실행

IEx에 접속하여 Cowboy업데터를 호출하는 방법이 아닌 명령행에서 직접 API서버를 실행할 수 있도록 해보자

mix.exe파일을 열어 application함수를 아래와 같이 변경하자

mod키를 추가하여, 어플리케이션이 시작될 때 실행할 시작 모듈을 MyApp으로 지정하였다.

 

메인코드로 와서 start함수를 추가하자(어플리케이션이 시작될때 호출되는 함수다)

마지막으로 터미널에서 다음과 같이 mix run 명령어를 실행하면,

 

학습참고 

https://www.usefulparadigm.com/2017/02/03/building-a-json-api-server-using-elixir-and-plug/

 

all? 

아이템 요소가 모두 만족해야 한다.

 

any? 

하나라도 만족하면 true를 반환한다.

chunk_every

컬렉션을 입력한 숫자로 쪼개기

 

chunk_by

열거할수 있는 함수를 받아와서, 주어진 함수의 결과 값이 변할 때 마다 그룹을 새로 시작한다.

map_every

모든 n번째 아이템을 가져오며, 항상 첫번째 것에도 적용한다.

 

each

새로운 값을 만들어내지 않고 컬렉션에 대해 반복한다.

 

map

각 아이템마다 함수를 적용하여 새로운 컬렉션을 만들어내고자 할때

 

min

컬렉션 내의 최소값

max

컬렉션 내의 최대값

 

reduce

컬렉션을 하나의 값으로 추려낸다. 선택사향으로 축적자를 함수에 전달이 가능하다.

 

sort

컬렉션 정렬

1)함수 사용x

2)함수 사용

 

uniq_by

열거 가능한 집합 내의 중복요소를 제거

 

 

Elixir School

프로그래밍 언어 Elixir 배우기

elixirschool.com

 

call by value(값에 의한 호출)

값을 복사해서 전달하기 때문에 원본의 값(매개변수로 넘겨준 값)이 변경될 가능성이 없다. 하지만 참조에 의한 호출보다는 고비용이다. 

 

call by reference(참조에 의한 호출) 

원본의 값의 변경이 될수도 있다. 

'프로그래밍언어 > C++' 카테고리의 다른 글

C++) 생성자와 소멸자  (0) 2020.06.10
C++)접근 제한자  (0) 2020.06.09
C) 배열/문자열과 포인터.  (0) 2020.05.02
C) 파일 입출력 (FILE,fopen,fclose)  (0) 2020.05.02
C) ASCII 아스키코드  (0) 2020.05.01

퍼센트등 int가 아닌 float를 이용한 수치계산이 이루어질때 생각했던 값과 다른 결과가 나오는데 부동소수점 방식은 실수를 정확히 표현할 수가 없다.

0.1을 10번더했으니 다행히 a는 1.0이라고 생각하면 안된다. 실수는 무한히 많은데 이 실수를 표현하기 위해서는 값으로 표현하기 떄문이다. 그래서 위 처럼 == 같음으로 비교하면 안되는것이다.

Epsilon을 사전적 의미를 검색 해 보니 수학에서는 매우 작은 수를 의미하는 기호로 자주 쓰인다고 한다.

C#에서 제공하는 Collections List와 LinkedList를 찾아 보게되었다. 사실 List는 사용하기가 편해서 워낙 많이 쓰이는 구조중 하나이다. List보다는 LinkedList를 좀 더 알기 위해 찾아봤다.

List

Add해서 데이터를 넣으면 입력한 중복이 가능하며, 순서대로 들어가게된다. Remove로는 해당 데이터를 삭제가 가능하다.

List.AddRange

AddRange를 통해 한꺼번에 입력이 가능하다. 다른 int형 리스트를 넣을 수 있다는 말

 

LinkedList

이중연결리스트형태를 가지고 있다. 리스트와 다르게 앞뒤 레퍼런스를 가지고 있으며, 앞(AddFirst), 뒤(AddLast)에 추가 할 수가 있다. 

물론 단순 1~4를 출력 하고싶으면 AddAfter( node , 3 ) value(3)값을 넣어도된다. 

노드 접근

다음 노드(node.Next.value) 이전 노드 (node.Previous.value)

이런식으로 특정 노드로 부 앞뒤로 데이터로 접근이 가능하다.

 

struct와 class의 차이점




1) Type차이



구조체는 값 타입(value)

=> 스택메모리에 생성된다.


클래스는 참조 타입(reference)

=> 힙 메모리에 생성된다.


힙과 스택차이점


값타입과 참조타입 관련 예제


구조체는 함수안에서 1로 변경을 해도 외부 Main에서 값이 변경되지 않는다. 복사된 데이터는 원본 데이터가 아니기 때문에 복사된 값을 수정하면, 스택에 복사된 값을 변경하게 되는것이다. 

(복사본에 입력된 값들은 함수가 끝나면 사라짐)


 클래스는 참조타입으로 힙의 주소를 전달하기 때문에 값이 아닌 같은 주소가 참조된다. 

그래서 Main으로 출력했을 때, 값이 변경되지 않고 원본값을 출력한다.

(변경된 데이터들은 함수가 종료되어도 남아있음)




  

2) 클래스와 비슷하면서도 다른 구조체


a. 구조체는 생성자를 선언할 수 있으나 반드시 파라미터가 있어야한다.

b. 구조체는 상속이 불가능하다.

c. 구조체는 필드선언 시 const또는 static으로 선언한 경우에만 초기화가 가능하다.

d. new연산자를 사용하지 않고 인스턴스화 할 수 있다.




메모리절약은 클래스, 속도는 구조체


인스턴스한다면 가비지 컬렉션(속도)

구조체는 스택에 바로 할당되기 때문에 가바지컬렉터션이 발생 하지 않고, 클래스는 인스턴스를 생성할 때 마다 힙에 메모리 할당하기 때문에 값을 폐기하기 위해서는 가바지컬렉션이 필요하다. 


많은 양의 변수를 가지고 있는 구조체는 NO(메모리)

참조형식인 클래스는 값들을 가리키는 주소만 스택에 저장하지만 구조체는 가지고있는 변수들의 값들을 모두 스택에 저장되기 때문에 그 크기만큼 스택의 위치 역시 커지게 된다. 하지만 스택은 크기가 제한적이기 때문에 너무 많은 양을 가지게 되면 스택 오버플로우가 발생할 수 있는 위험이 있다. 


구조체는 언제 사용할까?


상황에 맞게 사용해야 하는 구조체

변수의 크기가 작거나, 수명이 짧고, 자주 할당되는 객체는 구조체로 만들어 주는게 좋다.

유니티에서는 position, color, quaternion, rotation, scale등이 구조체로 구현 되어있다.



학습참고

1) https://vaert.tistory.com/111

2) https://m.blog.naver.com/PostView.nhn?blogId=wow0815&logNo=90184259071&proxyReferer=https%3A%2F%2Fwww.google.com%2F

3) https://nowonbun.tistory.com/84 

4) https://ronniej.sfuh.tk/c-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC-%EA%B5%AC%EC%A1%B0%EC%B2%B4-vs-%ED%81%B4%EB%9E%98%EC%8A%A4/


struct

단순 데이터 컨테이터용으로 50개의 struct를 사용해봅시다.


struct는 메모리를 많이 사용합니다.


A->B->C 로 값을 전달하면, 총 150 개의 struct 가 생성되게 됩니다.


레퍼런스와 관련된 처리가 없으므로 더 빠를 수 있습니다.


구조체는 스택에 할당되고, 자신을 호출한 함수가 종료되면 즉시 사라집니다.

GC를 유발하지 않고 빠르게 동작합니다.


오히려 더 느려질 수도 있습니다.


단일 struct 오브젝트의 크기가 너무 커지거나, 너무 긴 리스트에 넣고 쓰면, 복사하는 시간이 길어집니다. 이때 class 형보다 처리 시간이 더 길어질 수 있습니다.


변수가 2~3개 뿐인 단순한 데이터 컨테이너라면 struct 를 사용하는게 빠릅니다.

일반적인 경우에는 class 를 쓰세요.

'프로그래밍언어 > C#' 카테고리의 다른 글

C#) 키워드 간단 정리  (0) 2019.09.24
C#) List / LinkedList (List.AddRange)  (0) 2019.06.05
C#) 쓰레드(Thread), 프로세스  (0) 2019.02.22
C#) 리플렉션 Reflection  (0) 2019.02.20
C#) Action과 Func (람다식)  (0) 2019.02.16

 

쓰레드(Thread)

 

쓰레드 란?

쓰레드는 어떠한 프로그램 내에서 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 쓰레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티쓰레드라고 한다.

<위키 백과>

 

멀티프로세스와 멀티스레드는 양쪽 모두 여러 흐름이 동시에 진행되는 공통점이 있다. 하지만 멀티프로세스에서 각 프로세스는 독리적으로 실행되며 각각 별개의 메모리를 차지하고 있는 것과 다르게 멀티스레드는 프로세스 내의 메모리를 공유해 사용할 수 있다. 위키백과에서 나와 있듯이 쓰레드는 운영체제가 아닌 CPU시간을 할당하는 기본 단위이고, 프로세스는 하나 이상의 쓰레드로 구성 되는것이다.  또한 프로세스 간의 전환 속도보도다 스레드 간의 전환 속도가 빠르다. 

 

쓰레드의 상태

Unstarted

 쓰레드 객체를 생성한 후 Thread.Start() 메소드가 호출 되기 전의 상태

 Running

 쓰레드가 시작하여 동작 중인 상태.

 Unstarted 상태의 쓰레드를 Thread.Start() 메소드를 통해 이 상태

 Suspended

 쓰레드의 일시 중단 상태.

 쓰레드를 Thread.Suspend() 메소드를 통해 이 상태로 만들 수 있으며, Suspended 상태인 쓰레드는

 Thread.Resume() 메소드를 통해 다시 Running 상태

 WaitSleepJoin

 쓰레드가 블록(Block)된 상태

 쓰레드에 대해 Monitor.Enter(), Thread.Sleep(), Thread.Join() 메소드를 호출하면 이 상태

 Aborted

 쓰레드가 취소된 상태.

 Thread.Abort() 메소드를 호출하면 이 상태가 됩니다. Aborted 상태가 된 쓰레드는 다시 Stopped 상태로 전

 환되어 완전히 중지

 Stopped

 중지된 쓰레드의 상태

 Thread.Abort() 메소드를 호출하거나 쓰레드가 실행 중인 메소드가 종료되면 이 상태

 Background

 쓰레드가 백그라운드로 동작되고 있음, Foreground 쓰레드는 하나라도 살아 있는 한 프로세스

 가 죽지 않지만, Background는 여러개가 살아 있어도 프로세스가 죽고 사는 것에는 영향을 미치지 않는다.

 하지만 프로세스가 죽으면 Background 쓰레드는 모두 죽음. Thread.IsBackground 속성에 true 값을

 입력하면 쓰레드를 이 상태로 바꿀 수 있음.

 

쓰레드 라이프 싸이클

 

 

쓰레드 간단한 예제



 

 

학습 참고 :

 

1)  https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%A0%88%EB%93%9C_(%EC%BB%B4%ED%93%A8%ED%8C%85)

2) https://nshj.tistory.com

3) https://codedragon.tistory.com/3526

4) https://dlgnlfus.tistory.com/295

5) https://acroama.tistory.com/m/43

 

리플렉션 Reflection


실행 중(런 타임)에 클래스나 객체의 타입 정보를 조사하는 기능, 리플렉션을 사용하여 형식의 인스턴스를 동적으로 만들거나, 형식을 기존 개체에 바인딩하거나, 기존 개체에서 형식을 가져오고 해당 메서드와 속성을 액세스 할 수 있다.(형식 이름, 포로퍼티, 메소드, 필드, 이벤트 목록을 모두 볼수 있고, 해당 메소드를 호출하거나 필드, 프로퍼티에 접근하는 것도 가능하 다는 것임)

타입 정보는 보통 컴파일 중에만 사용되며 컴파일러에 의해 기계어로 바뀌고 나면 사라지는 것이 일반적이다 하지만 C#은 컴파일된 결과 코드 뿐만 아니라 타입에 대한 메타 데이터를 실행 파일에 같이 기록해 놓기 떄문에 실행중에도 정보를 조사할 수 있다.


접근방법

지정된 이름으로 접근

1) Type t = Type.GetType("Test");


클래스 타입으로 접근

2) Type t = tyoeof("Test");


객체로 접근

3) Type t = Test.GetType()


프로그램의 metadata에 접근할 수 있도록 해주는 이 클래스는 System.Refelection namespace에 정의 해 주어야한다.

해당 메서드와 멤버변수들을 불러 올수 있다.







학습 참고

1) http://www.csharpstudy.com/Practical/Prac-reflection.aspx

2) https://hsj0511.tistory.com/350

3) https://hongjinhyeon.tistory.com/86


Action과 Func (람다식)


Action

Action은 파라미터가를 받아 들이는데, 리턴 값이 없는 함수에 사용되는 Delegate이다.


Action은 쓰려면 네임스페이스에 선언해줘야한다.

using System;

무명메델리게이트와 다른 Action 델리게이트

delegate void MyDelegate<T1, T2>(T1 a, T2 b); 와 다르게 네임스페이스에 선언한 System에 Action은 유니티시스템에 이미 정의되어있다.



Func 


Func는 Action과 비슷한데, 리턴값이 있을 경우 사용한다.

3번째 는 반환값 타입을 입력해줘야한다.


실제사용 코드 

테이블종류를 넣고 데이터를 리스트에 추가하는 코드이다, 여기서도 Action<bool>을 사용하였다. 



학습참고 : https://www.youtube.com/watch?v=7H3MHXfFkhI&index=19&list=PLUZ5gNInsv_O7XRpaNQIC9D5uhMZmTYAf

http://www.csharpstudy.com/Tip/Tip-Func.aspx



암시적 변환


C#은 컴파일 타임에서 정적으로 데이터 형이 지정된다. 변수의 형을 변환 하지 않으면 다시 선언하거나 다른 형태의 값에 넣는 것이 당연히 불가능하다,예외가 있는데 바로 암시적 변환 될 경우다.


형식이 안전하고 데이터가 손실되지 않으므로 특수 구문이 필요하지 않는다. 


1) 파생클래스 -> 기본클래스로 변환



2) 동일 데이터형의 큰타입으로 변환






명시적 변환(캐스트)


명시적 변환은 캐스트가 필요하다. 변환 시 정보가 손실 될 수도 있고, 암시적으로 변환된 작은 타입에서 큰타입으로 변환되는데 값의 손실이 없었지만 반대(큰타입->작은타입)는 값 손실이 있다.


그냥 변환하는것이 불가하고 캐스팅 키워드를 이용해야 한다.

앞에 '( 타입 )' 써준다.


1) 기본클래스 -> 파생클래스


2) (같은 타입)작은자료형 -> 큰자료형




학습참고 : https://guslabview.tistory.com/68

https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/types/casting-and-type-conversions

C#) 네임스페이스



가끔 "네임스페이스에 형식또는 네임스페이스 이름이 없습니다."라는 문구를 볼때가 있다.

네임스페이스를 알아보기 전에 작업 하다가 생긴 오류를 살펴보자


Define클래스

인터페이스나 enum같은 경우는 Defie클래스를 만들어서 한 곳에 정의하였다.


인터페이스를 사용하려는 클래스

아까 정의한 인터페이스를 사용하려는데? 

오류가 났다. 바로 'Global_Define' namespace를 선언해 주지 않았기 때문이다.


예시

콘솔창에서 텍스트를 출력하는 Console이 오류가 났다. 

이유는 System이라는 namespace가 없기 때문이다. 


Console클래스 정의로 이동해봤다.

Console이라는 클래스에는 WirteLine( )이라는 메서드가 있었다. 


Console이라는 클래스는 System 네임스페이스의 정의 되어있다.

System은 -> 네임스페이스

Console은 -> System의 정의되어있는 클래스

WirteLine은 -> Console클래스 에 정의된 메소드


네임스페이스 정의방법

첫 번째 

맨 윗단에 해당 using을 사용하여 C#파일에서 사용하고자 할때

두 번째

클래스명 앞에 네임스페이스 전부를 적는 경우 이 경우는 네임스페이스 안의 메소드, 

변수를 사용하려면 앞에 매번 적어줘야함 



네임스페이스는 즉 

소속이라는 정의하는 역할을 하는 것이다. 

네임스페이스를 귀찮게 나눠서 쓰는 이유.

이름이 같은 변수,메소드등등 이지만 실행되는 내용들은 다를 수 있기 떄문이다. 

A프로그램과 B프로그램이 있는데 같은 이름을 사용하지만 그 내용들이 조금 다르면?

프로젝트가 커지고 스크립트 수가 증가할수록 스크립트 클래스 이름이 충돌할 가능성이 커집니다. 이것은 게임의 다른 파트를 ​​따로 작업하고 궁극적으로 같은 프로젝트에 통합하는 경우에 적용됩니다. 예를 들어 한 명의 프로그래머가 메인 플레이어의 제어 코드를 만들고, 또 한사람이 적 캐릭터의 제어 코드를 작성했다고합니다. 둘 다 기본 스크립트 클래스를 Controller 라고 명명하고 프로젝트를 통합할 때 이름이 충돌합니다.

<유니티도큐>


유니티에 생성되는 namespace

유니티에서 스크립트를 생성하면 자동으로 추가 되는 것들이다. 클래스에서 Start나 Update메소드가 자동으로 생성되지만 있는 존재만으로도 비용이 들기 때문에 사용하지 않으면 삭제한다. namespace도 마찬가지이다. 사용하지 않으면 지워주자



학습참고 : 

1) https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/namespaces/

2) https://thinkpro.tistory.com/22

3) http://www.csharpstudy.com/csharp/CSharp-namespace.aspx


객체지향 언어와 절차지향 언어 차이점



절차지향 언어

프로그램의 프로세스 흐름을 표현하는데 비중


객체지향 언어

데이터나 정보의 표현에 비중

데이터와 함수를 하나의 덩어리로 묶어서 생각하는 방법


절차지향 언어는 대표적으로 C언어가 있다. 컴퓨터의 작업처리 방식과 유사하기 때문에 객체지향 언어를 사용하는 것보다 속도가 빨랐다. 

하지만 지금은 기술발전으로 소프트웨어가 발달로 절차지향과 객체지향언어는 속도차이가 거의 나지 않음 뿐더러

객체지향 언어는같은 기능을 중복으로 사용하는 경우를 없애고, 모듈을 재활용하기 때문에 하드웨어가 감당하는 처리량을 많이 줄 뿐만 아니라  새로운 기능을 수정,추가 하는 유지보수, 캡슐화로주변에 미치는 영향을 최소화 해준다. 


객체지향 프로그래밍은 실행절차에 영향을 받지 않는 프로그램 기법인 것처럼 생각할 수 있지만, 구조와 모듈을 먼저 설계한 다음에 실행순서와 흐름을 짜는 방식일뿐, 객체지향방식으로 개발한 프로그램도 절차에 따라 실행된다. 


객체지향언어의 장점이 더 많지만 코드의 사이즈를 최소화 하고 빠른 동작이 필요한 프로그램이면 절차지향언어로 개발하는게 맞는것 처럼, 프로그램의 목적의 맞게 선택해서 개발해야한다.




학습참고

1) http://blog.wishket.com/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-vs-%EC%A0%88%EC%B0%A8%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/

2) https://sesok808.tistory.com/32


'프로그래밍언어' 카테고리의 다른 글

실수비교/ Epsilon 엡실  (0) 2019.06.09
오버로딩,오버라이딩 Overloading / Overriding  (0) 2019.01.19

boxing/unboxing


박싱/언박싱?


내가 알고 있는 박싱/언박싱은 자료의 형변환이 일어날때

값 형식을 참조형식으로 박싱

참조형식을 값형식으로 언박싱이다 라는정도인데 메모리영역에서 어떻게 일어나는지 알아보았다.


박싱

값 형식을 참조 형식으로 변환되는 것을 말한다. 

static void Main(string[] args)

{ int i = 93; object s = i; //박싱 }

int i 는 93이라는 값을 받고, object s는 i의 값을 받고있다.

값 형식인 정수형 자료 int를 object(참조형식)객체로 할당하게 되면 박싱이 일어나게 된다.


=> 스택에 있는 데이터가 힙으로 복사 된 것이다.


Stack에 있는 93이라는 정수형 자료가 Heap영역으로 복사되고, 이영역을 객체 변수 s가 가리키게 된다.



언 박싱

참조 형식을 값 형식으로 변환하는 것,

static void Main(string[] args) { int i = 93; object s = i; int j = (int)s; //언 박싱(명시적 변환) }

s를 int로 값 형식으로 변환한다. 

박싱된 객체인 s를 다시 값 형식으로 변환하면 언박싱이 일어난다.


=> 힙에 있는 데이터가 스택으로 복사된다.



언 박싱이 가능한 객체

값 형식을 박싱하여 생성된 객체이어야만 가능

static void Main(string[] args) { short i = 93; object s = i; int j = (int)s; //언 박싱 불가 }

short타입을 박싱한 객체를 int타입으로 언 박싱은 불가능

해당 타입보다 작은 범위로 변환 불가능



높은 비용의 박싱/언박싱

박싱과 언박싱은 많은 시간이 소모된다고 한다. 되도록 제네릭을 사용해서 박싱과 언박싱이 일어나지 않도록 구성하도록 하는게 좋다.


박싱의 과정 : 

1. 값 타입을 힙에 생성하기 위해 메모리를 힙 영역에 생성

2. 값을 힙 영역에 할당된 메모리로 복사

3. 참조할 변수에 할당된 메모리 주소를 할당


언박싱의 과정 :

1. 박싱값인지 확인

2. 박싱된 값이라면 값 타입 변수에 복사

3. 박싱한 메모리와 언박싱한 메모리 2개 존재 ( 가비지 발생 )



학습참고 : http://www.mkexdev.net/Article/Content.aspx?parentCategoryID=1&categoryID=5&ID=671

 https://grayt.tistory.com/87 [IT's me]

https://hongjinhyeon.tistory.com/90


ref 키워드 (참조자)


C++에서 참조자 & 있다면 C#에는 단순히 참조를 하기위한 ref키워드가 있다. 

값형식이든 참조 형식이든 둘다 스택에 있는 값이 복사된다.


값 형식 : 스택영역메모리에 값이 직접 들어가있어서 그것이 복사된것

참조 형식 : 스택영역메모리에 힙영역의 주소가 들어있어서 그 주소가 복사되면서 같은 객체를 가리 킴

ref키워드를 이용하면 스택영역 메모리의 주소를 사용하면서 Call by reference를 사용하게된다. 


예제코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        static void Main(string[] args)
        {
            int a = 100;
            int b = 200;
            swapvalue(ref a, ref b);
            Console.WriteLine("변수{0}에 들어있는 수는{1}입니다.""a", a);
            Console.WriteLine("변수{0}에 들어있는 수는{1}입니다.""b", b);
 
        }
        static void swapvalue(ref int a, ref int b)
        {
            int temp = a;
            a = b;
            b = temp;
        }


a값과 b값이 변경되었다.


out 키워드 (참조자)


out키워드도 Call by reference를 가능하게 하는 키워드이며 

'출력용 매개변수'라고도 하여 값을 읽을 수 없는 쓰기용이다.

ref와 다른 특징들이 있다.


1. 현재 메소드가 끝나기 전에 out키워드가 붙은 변수는 값을 할당 받아야한다.

1
2
3
4
5
6
7
        static void swapvalue(ref int a, ref int b, out int c)
        {
            int temp = a;
            a = b;
            b = temp;
  //c 변수는 값을 할당 받아야한다.
        }

cs


2. out 키워드가 쓰인 변수는 함수내에서 값을 읽을 수 없다.

1
2
3
4
5
6
7
8
        static void swapvalue(ref int a, ref int b, out int c)
        {
            int temp = c; //에러
            a = b;
            b = temp;
            c = a;
 
        }
cs


예제코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        static void Main(string[] args)
        {
            int a = 100;
            int b = 200;
            int swapA ; //값 초기화 의미 X
            int swapB;  //값 초기화 의미 X
            swapvalue(a,b, out swapA, out swapB);
            Console.WriteLine("변수{0}에 들어있는 수는{1}입니다.""a", swapA);
            Console.WriteLine("변수{0}에 들어있는 수는{1}입니다.""b", swapB);
 
        }
        static void swapvalue(int a,int b, out int swapA, out int swapB)
        {
            swapA = b;
            swapB = a;
        
        }
cs


ref와 기능이 같은데 out키워드를 쓰는 이유?

ref키워드를 이용해서 매개 변수를 넘기는 경우에는 메소드가 해당 매개변수에 결과를 저장하지 않더라도 컴파일러는 아무런 경고를 하지 않는다.

하지만 out 키워드는 매개변수를 넘길 때 메서드가 해당 매개변수에 결과를 저 정하지 않으면 컴파일러 에러를 주면서 강제적으로 제한을 준다.

 또 첫 번째처럼 초기화를 하지 않아도 되는 이유는 호출당할 때 값을 할당할 것을 보장하기때문이다. 프로그램이 실행됐을 때가 아닌 코드를 작성하는 중에 컴파일 과정 에러를 확인할 수 있다.



공부참조

https://grayt.tistory.com/90?category=683217

https://runtoyourdream.tistory.com/279

https://grayt.tistory.com/90?category=683217

'프로그래밍언어 > C#' 카테고리의 다른 글

C#) 네임스페이스 / 유니티 네임스페이스  (0) 2019.02.13
C#) 박싱/언박싱 (boxing/unboxing)  (0) 2019.02.10
C#) Lamda #2  (0) 2019.02.07
C#) Lamda 람다 식  (0) 2019.02.06
C#) Generics 제네릭 클래스  (0) 2019.02.04

람다 Lamda  #2





앞서 공부한 

델리게이트를 써서 sum값을 출력해봤다.

//결과 값 15


이번에는 Print함수를 작성하지 않고 

무명메소드로 sum을 출력해봤다.

 //결과 값 15


이번에는 

람다식으로 sum을 출력했다.

// 결과 값 15


마지막으로

형식 매개변수를 이용해서 람다 식을 사용해 봤다.

// 결과 값 15 (유니티 디버그로 출력)

'프로그래밍언어 > C#' 카테고리의 다른 글

C#) 박싱/언박싱 (boxing/unboxing)  (0) 2019.02.10
C#) ref 키워드 (참조자) , out 키워드  (1) 2019.02.09
C#) Lamda 람다 식  (0) 2019.02.06
C#) Generics 제네릭 클래스  (0) 2019.02.04
C#) 비트연산자  (0) 2019.01.30

 Lamda 람다 식




람다 식은 대리자또는 식트리 형식을 만드는 데 사용할 수 있는 익명 함수이다.

람다 식을 사용하여 인수로 전달되거나 함수 호출값으로 반환되는 로컬 함수를 쓸 수 있다.


작성법

' => ' 왼쪽에 입력 매개 변수를 지정(있는 경우) 다른 쪽에 식이나 문 블록을 넣는다.


delegate int del(int i); static void Main(string[] args) { del myDelegate = x => x * x; int j = myDelegate(5); //j = 25 }




람다 식

무명 메소드를 단순한 계산식으로 표현 한 것이다.

메소드는 매개변수, 내부 식, 반환 값으로 구성 되어 있는데 이들을 가지고 메소드를 계산 식으로 표현할 수 있다.(=람다 식)



먼저 무명 메소드를 보면

매개변수 타입, 내부의 { } 내부 식, 반환 값을 입력 해주어야 한다.


무명메소드를 람다 식으로

 매개변수 타입, { }안 내부 식,내부 반환 값이 생략이 가능하다.




https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions

'프로그래밍언어 > C#' 카테고리의 다른 글

C#) ref 키워드 (참조자) , out 키워드  (1) 2019.02.09
C#) Lamda #2  (0) 2019.02.07
C#) Generics 제네릭 클래스  (0) 2019.02.04
C#) 비트연산자  (0) 2019.01.30
C#) abstract, virtual, override  (0) 2019.01.26


Generics 



일반적으로 클래스를 생성할 경우 각 데이터마다 타입을 지정해준다. 다른 데이터형을 사용하게 될 경우가 있는데, 강제 형변환은 좋지않다고 한다. 그래서~ 제네릭을 사용한다.


제네릭은 박싱/언박싱(형변환)이 일어나지 않도록 타입을 미리 지정하는 방식이다.

클래스,인터페이스, 메서드등에서도 구현 가능하다.


참조 타입 --> 힙 (Heap)

값 타입    --> 스택(Stack)

두 메모리 영역을 왔다갔다는 좋지않음


많이 사용했던 컬렉션들에서 이미 제네릭을 사용하고 있었다.


<출처 :  https://m.blog.naver.com/rocabilly/140133375098 >



Generics에서는 int, float, double같은 데이터 요소 타입을 확정하지 않고 이 데이터 타입 자체를 파라미터로 받아들이도록 클래스를 정의한다. 


형태

class 클래명 <T>

{

T 변수명;

}


public 메소드명 (T 변수명)

{

T 내부 변수명;

}

}


테스트 예제 코드

<결과>

이렇게 다른타입도 제네릭을 통해 원하는 결과를 도출 할 수 있다.




Generics 제약 Where


타입 파라미터가 값형식인지 참조 타입인지, 사용자가 정의한 베이스 클래스로부터 파생된 타입인지, 

어떤 인터페이스를 구현한 타입인지 등등을 지정 할 수 있다. 

제약을 걸어 사용자가 원하지 않는 형식의 매개변수를 넘기는 상황을 방지 할 수 있다.


형태

class 클래스명<T> where T : 제약형식

class 메소드명<T> where T : 제약형식

value(값) 타입

class MyClass<T> where T : struc


Reference(참조) 타입

class MyClass<T> where T  : class


T가 파생 클래스 일때

class MyClass <T> where T : MyBase


인터페이스

class MyClass <T> where T : Myinterface

등등..


2개 이상 제약이 가능함

class 클래스명<T,V> where T : 제약형식1, 제약형식2 where V : 제약형식


where <NAME> : <TYPE> 조건에 대한 제약사항

1) 구조체 및 정적 클래스는 사용할 수 없다.

2) 특수형식(object, Array, Delegate등)은 사용 불가

3) class와 struct조건은 같이 사용 불가




학습한 자료 사이트

http://www.csharpstudy.com/

https://m.blog.naver.com/rocabilly/140133303502

https://slaner.tistory.com/126

감사합니다.

'프로그래밍언어 > C#' 카테고리의 다른 글

C#) Lamda #2  (0) 2019.02.07
C#) Lamda 람다 식  (0) 2019.02.06
C#) 비트연산자  (0) 2019.01.30
C#) abstract, virtual, override  (0) 2019.01.26
C#) Delegate 콜백메서드,Delegate 체인 #3  (0) 2019.01.25

비트연산자



비트 단위로 논리 연산하고 비트 이동 연산을 수행하는 연산자이다.

실행속도와 표현의 편리성때문에 많이 사용된다고 한다.


& 비트단위 AND

| 비트단위 OR

^ 비트단위 XOR

<< 왼쪽으로 1비트 이동

>> 오른쪽으로 1비트 이동


<결과>




'프로그래밍언어 > C#' 카테고리의 다른 글

C#) Lamda 람다 식  (0) 2019.02.06
C#) Generics 제네릭 클래스  (0) 2019.02.04
C#) abstract, virtual, override  (0) 2019.01.26
C#) Delegate 콜백메서드,Delegate 체인 #3  (0) 2019.01.25
C#) 델리게이트 #2  (0) 2019.01.24

abstract (추상)


먼저 간단한 예제를 테스트해봤다.

1) 메서드에 abstract을 사용하려면 해당 클래스도 abstract로 선언되어야 한다.

2) abstract 키워드로 표시한 속성이나 메서드는 본문을 정의할 수 없고, 

파생된 자식클래스에서 이 메서드를 정의 할 수 있다.(반드시 정의 해야함)

3) 접근 한정자 private은 사용이 불가하다.

4) 새로운 개체 생성이 불가능하다. (파생 클래스로 생성가능)


.


Virtual (가상)

Virtual도 간단한 예제를 테스트 해봤다.

1) 메서드에 virtual 키워드를 붙여야한다.

2) 접근 한정자 private은 사용이 불가하다

3) abstract과 다르게 본문을 정의 할 수 있다. (괄호만 치고 비워 놓아도 됨)

4) 파생클래스에 base. 키워드를 쓰면 부모 클래스에있는 메소드에 있는 내용 실행할 수 있음

(Parents클래스의 test에 접근한다는 것임) 

<실행결과>


override

override키워드는 위에서 사용한 것 들을 보면 부모클래스에서 선언,정의한 내용을 상속을 받은 자식클래스에서 매서드를 재 정의 할때 사용 한다는 것을 알 수 있다. opp지향 언어의 다형성을 잘 보 여 주는 키워드이다.





'프로그래밍언어 > C#' 카테고리의 다른 글

C#) Generics 제네릭 클래스  (0) 2019.02.04
C#) 비트연산자  (0) 2019.01.30
C#) Delegate 콜백메서드,Delegate 체인 #3  (0) 2019.01.25
C#) 델리게이트 #2  (0) 2019.01.24
C#) 델리게이트(delegate) #1  (0) 2019.01.23

Delegate 콜백 메서드


콜백이란?_

A라는 메서드를 호출할 때, B라는 메서드를 매개변수로 넘겨주고 A메서드에서 B메서드를 호출하게 되는것이다.


Delegate 체인

델리게이트는 하나의 메소드만 참조하는 것이 아닌 여러개 메서드를 참조 할 수 있다.

추가 연산(+=)을 통해 메서드를 추가 할 수 있다. 

-=을 통해 빼기도 가능하다.



델리게이트는 해당 클래스 내부 뿐만 아니라 다른 클래스에서도 이 델리게이트를 호출 할 수 있는 장점이자 단점인 위험이 존재한다. 추가 연산(+=)이 아닌, 할당 연산(=)을 하게 되면 기록된 메서드를 모두 지워지니 조심해야한다.



'프로그래밍언어 > C#' 카테고리의 다른 글

C#) 비트연산자  (0) 2019.01.30
C#) abstract, virtual, override  (0) 2019.01.26
C#) 델리게이트 #2  (0) 2019.01.24
C#) 델리게이트(delegate) #1  (0) 2019.01.23
c#) 스태틱 Static 변수,메서드,클래스  (4) 2019.01.16

델리게이트 #2


Delegate를 메서드 파라미터로 전달

델리게이트는 메서드 타입(동일한 리턴타입&파라미터)이어야 사용할 수 있다.




MyDelegate 델리게이트는 리턴타입과 파라미터가 string으로 선언 되어 있고,

델리게이트로 사용 할 메서드들도 타입들도 string으로 정의 되어있다.

27번줄 : del = new MyDelegate(StringtestTwo); 을 줄여서 쓸수 있다.

<출력 결과>



 참고 : http://www.csharpstudy.com/CSharp/CSharp-delegate.aspx

+ Recent posts