오브젝트를 쓸려고하면 형변환을 하고 써야한다.
모든 타입을 소화가 가능함.
var로 변수를 선언할경우 컴파일러가 자동으로 타입을 변환해주지만, object를 사용할경우에는 형변환을 하고 써야한다.
Object가 모든 형식을 쓸 수 있는이유?
결론적으로 말하면 상속 때문이다. int,string 형식이 object를 상속받기
때문이다.
int num = 3;(복사타입)
참조타입에 저장하고 다시 사용하기 위해서는 힙에서 꺼내와서 다시 스택에 저장하는 방식이라서 낭비가 심하다(박싱, 언박싱)
object obj = 3; //3(참조타입) 박싱
int num2 = (int)obj //언박싱
값타입은 스택에 저장, 참조타입은 힙에 저장
박싱 : 값타입의 객체를 참조타입으로 변환
언박싱 : 참조타입을 값 타입으로 변환
리스트나 딕셔너리를 사용할 때, 어떤 데이터를 리스트 안에서 사용할 지 자료형을 설정합니다.
using System;
using System.Collections.Generic;
namespace Example
{
class Program
{
// 실행 함수
static void Main(string[] args)
{
// int타입을 다루는 List의 인스턴스를 생성
var list = new List<int>();
// list에 데이터를 입력
list.Add(1);
list.Add(2);
// list의 값을 순서대로 출력
foreach (int node in list)
{
// 콘솔 출력
Console.WriteLine(node);
}
// 아무 키나 누르시면 종료합니다.
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
클래스나 메소드 안에서는 데이터 타입을 정하지 않고, 인스턴스를 생성하는 위치에서 데이터 타입을 설정하여 사용하는 방법의 의미이다.
using System;
using System.Collections.Generic;
namespace csharp
{
class Program
{
class MyList<T>
{
T[] arr = new T[10];
public T GetItem(int i)
{
return arr[i];
}
}
static void Test<T>(T input)
{
}
static void Main(string[] args)
{
MyList<int> myIntList = new MyList<int>();
int item = myIntList.GetItem(0);
Test<int>(3);
Test<float>(3.0f);
}
}
}
이런식으로 2개이상도 사용이 가능하다.
class MyList<T, K>
{
}
제네릭타입에 조건 추가도 가능(C++에는 없다)
class MyList<T> where T : struct //반드시 T는 값(복사)형식이다
class MyList<T> where T : class //반드시 T는 참조형식이다.
class MyList<T> where T : new() //반드시 어떠한 인자도 받지않는 기본 생성자여야한다
class MyList<T> where T : Monster //반드시 Monster혹은 몬스터를 상속받은 클래스여야 한다.
이런식으로 T에 대한 타입제한을 걸어 놓을수도 있다.