C#는 객체지향언어이다.
문법은 C++보다는 JAVA에 가까운 문법이다.
C#의 접근 제어자는 다음과 같다 : internal, protected internal, protected, private, public
C#에만 있는 것이 internal인데, 같은 어셈블리 파일에서만 접근이 가능하다는 것이 특징이다. 여기서 어셈블리 파일이란 CIL, *.exe, *.dll을 뜻한다.
protected internal은 다른 어셈블리 파일이더라도 상속을 받았다면 사용가능하다는 것을 의미한다.
C#에서는 일반적인 어셈블리를 얘기하지않고, CIL을 어셈블리라고 부른다.
C#의 기본 접근제어자는 private이며, 다음과 같이 사용한다.
using System;
namespace study4
{
class Study
{
private int count;
public Study() : this(0) // 아래있는 생성자 호출
{
Console.WriteLine("기본 생성자 호출!");
}
public Study(int count){
this.count = count;
}
public void CountPlus(int count = 1)
{
this.count += count;
}
public void Print()
{
Console.WriteLine($"Count : {count}");
}
}
class Program
{
static void CountPlus(Study study)
{
study.CountPlus(100);
study.Print();
}
static void Main(string[] args)
{
Study study = new Study();
study.Print();
study.CountPlus(10);
study.Print();
study.CountPlus();
study.Print();
CountPlus(study);
study.Print();
}
/* 출력
기본 생성자 호출!
Count : 0
Count : 10
Count : 11
Count : 111
Count : 111
*/
}
}
보다시피 C++보다는 JAVA에 가깝다.
Main함수에 study는 힙 메모리에 new한 Study 인스턴스를 담는 레퍼런스이다.
그렇다보니 Program클래스의 CountPlus로 study를 인자로 넘겨줄 경우, 자동으로 reference가 넘어가게 된다. 따라서 해당 함수에서 값을 수정해도 Main함수의 study 또한 값이 변경된다. 이는 자바와 유사하다.
using System;
namespace Study6
{
class Program
{
struct Struct
{
public int x;
public int y;
public int z;
}
static void ControlStruct(Struct st)
{
st.x = 10;
st.y = 20;
st.z = 30;
}
static void ControlStructRef(ref Struct st)
{
st.x = 10;
st.y = 20;
st.z = 30;
}
static void Main(string[] args)
{
Struct st;
st.x = 1;
st.y = 2;
st.z = 3;
ControlStruct(st);
Console.WriteLine($"x:{st.x}, y:{st.y}, z:{st.z}");
// 출력 값 : x:1, y:2, z:3
ControlStructRef(ref st);
Console.WriteLine($"x:{st.x}, y:{st.y}, z:{st.z}");
// 출력 값 : x:10, y:20, z:30
}
}
}
C#의 구조체는 유의할 점이 있다.
C++의 경우 struct를 class와 동일 시 하는 경향이 있다. 실제로 struct를 상속해서 사용하는 등 struct == class 나 다름없었지만, C#에서는 struct가 조금 별종이다.
보다시피 Struct를 참조 레퍼런스 자료형으로 보지않는다. 즉, new로 동적할당해야 하는 것이 아니라, 지역변수로 설정된다. 따라서 일반 자료형과 같이 사용해야 한다.
또 주의할 점으로 Struct의 경우 접근제어자도 꼭 써야 한다. 기본 접근제어자가 private이기 때문이다. C++에서는 Struct의 기본 접근제어자가 public인 것과 차이가 존재한다.
using System;
namespace Study7
{
class Program
{
enum Enum
{
a, // 0
b, // 1
c = 5, // 5
d = 10, // 10
e = 25, // 25
f // 26
}
static void Main(string[] args)
{
Console.WriteLine($"a:{Enum.a}, b:{Enum.b}, c:{Enum.c}, d:{Enum.d}, e:{Enum.e}, f:{Enum.f}");
// a:a, b:b, c:c, d:d, e:e, f:f
Console.WriteLine($"a:{(int)Enum.a}, b:{(int)Enum.b}, c:{(int)Enum.c}, d:{(int)Enum.d}, e:{(int)Enum.e}, f:{(int)Enum.f}");
// a:0, b:1, c:5, d:10, e:25, f:26
Enum b;
b = Enum.b;
if(b == Enum.b)
Console.WriteLine("b is b");
// b is b
}
}
}
C#의 Enum은 C의 Enum과 비슷하다. C처럼 자동으로 순서대로 0부터 1씩 늘린다. 주의할 점은 f다 e가 25이다보니 5가 아닌 26을 할당해줬다.
또 Main함수에서 보면 Enum을 사용할 때 숫자 값을 얻고 싶으면 (int)형으로 강제 형 변환을 시켜줘야 한다.
보다시피 Enum 또한 지역변수로 선언되기 때문에 copy로 함수로 넘어간다. 따라서 만약 참조 레퍼런스를 원한다면 ref 키워드를 작성해야 한다.