1. Main 코드 (가장 기초적으로 만들어지는 코드 전문)
- 개인적으로는 Java를 먼저 배우고 C#을 배우는 입장으로서 Java와 매우 유사하다고 생각한다.
- #include -> using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
2. Console.WriteLine()
- printf()와 std::cout 를 섞어놓은 출력 방식이라고 느꼈음.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int a = 12345;
Console.WriteLine("|{0,15}|", a);
Console.WriteLine("|{0,-15}|", a);
Console.WriteLine("|{0,15:N0}|", a);
Console.WriteLine("|{0,-15:N0}|", a);
}
}
}
3. Console.ReadLine()
- scanf() 혹은 std::cin 의 기능
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("수를 입력하세요 : ");
string line = Console.ReadLine();
Console.WriteLine("출력 : " + line);
}
}
}
4. string to int 변환
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "123";
int integer = int.Parse(str);
Console.WriteLine(integer);
}
}
}
5. Call By Value & Call By Reference
- 포인터(*), 주소 참조(&)의 선언 개념없이 ref 로 주소 전달을 할 수 있는 것으로 보인다.
- class 함수 내의 메소드들은 static을 추가.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void testSwap(int a, int b)
{
int temp = b;
b = a;
a = temp;
}
static void testSwap(ref int a, ref int b)
{
int temp = b;
b = a;
a = temp;
}
static void Main(string[] args)
{
int num1 = 10;
int num2 = 20;
Console.WriteLine("before {0}, {1}", num1, num2);
testSwap(num1, num2);
Console.WriteLine("after {0}, {1}", num1, num2);
Console.WriteLine("using ref");
testSwap(ref num1, ref num2);
Console.WriteLine("after {0}, {1}", num1, num2);
}
}
}
6. 배열을 전달하는 방법 (parmas)
- 매개변수에 'params' 키워드를 붙여 배열을 편하게 전달할 수 있다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void testParams(params int[] list)
{
Console.WriteLine("list Size : " + list.Length);
foreach(int data in list)
{
Console.Write(data + " ");
}
}
static void Main(string[] args)
{
Console.WriteLine("Params Test");
testParams(10, 20, 30, 40, 50, 60, 70);
}
}
}
7. System.Arrays
- 차수, Clear 등 배열을 다루기 위한 방법을 제공.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("System.Arrays Test");
int[] reading = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Rank
Console.WriteLine("Rank" + reading.Rank);
// Clear
Console.WriteLine("Clear !");
Array.Clear(reading, 0, 5);
// ForEach
Array.ForEach<int>(reading, new Action<int>(ShowValue));
}
}
}
8. 다차원 배열 선언
- C#에서도 역시 다차원 배열을 선언할 수 있으나 선언 방법이 가장 새롭다(?) 라고 생각했다.
int[,] multiReading = new int[1, 2];
9. 접근 제한자(internal, protected internal)
- internal
> 동일한 어셈블리의 코드에서는 형식이나 멤버에 액세스 할 수 있지만
다른 어셈블리의 코드에서는 액세스 할 수 없다. (프로젝트 내에서만 접근 가능)
> Helper Class를 만드는데 주로 사용.
- protected internal
> 형식 또는 멤버가 선언된 어셈블리의 모든 코드에서 또는 다른 어셈블리의 파생 class 내에서
형식 또는 멤버에 액세스 할 수 있다.
> 어셈블리 내의 상속 클래스에서만 접근 가능.
* 어셈블리
> 한 프로젝트가 반환하는 결과물. (.exe or .dll)
10. 클래스 상속 중 sealed
- 클래스명 앞에 'sealed' 키워드를 사용하면 해당 클래스는 상속 할 수 없다. (부모 클래스로 사용하지 못 함)
11. 클래스 멤버 변수에 대한 get / set
- 정보 은닉을 위한 getter 과 setter 를 키워드로 제공.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public class MyClass
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine("mc name : " + mc.Name);
mc.Name = "matagi";
Console.WriteLine("mc name : " + mc.Name);
}
}
}
- 위 get과 set을 C# 3.0 이후 부터 아래와 같이 축약하여 사용할 수 있다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public class MyClass
{
public string Name { get; set; } = "empty";
}
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine("mc name : " + mc.Name);
mc.Name = "matagi";
Console.WriteLine("mc name : " + mc.Name);
}
}
}
12. 확장 메소드
- 이미 빌드된 라이브러리를 참조해 사용 중이며 이 라이브러리의 기존 클래스 기능을 좀 더 확장 시키고 싶을 때 사용.
하지만 라이브러리의 소스 코드가 없기 때문에 클래스를 직접 수정 불가능 할 때 사용.
- 상속도 하나의 방법이 될 수 있지만, 클래스가 sealed로 한정되어 있는 경우 확장 메소드의 사용을 고려할 수 있다.
using System;
using Extenstion;
namespace Extenstion
{
public static class ExtensionMethod
{
public static int Multiplication(this int var, int a, int b)
{
int result = var;
for (int i = a; i <= b; i++)
result += i;
return result;
}
}
namespace Example
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("{0}", 5.Multiplication(2, 3));
}
}
}
}
13. 분할 클래스(Partical Class)
- 클래스의 구현이 길어질 경우 두 개 이상의 소스 파일로 분할하여 동시에 작업을 수행하거나,
관리의 편의를 위해 클래스를 분할하기도 한다.
- 클래스를 분할할려면 'partical' 키워드를 사용한다.
using System;
namespace Example
{
partial class Nested
{
public void Test() { Console.WriteLine("Test()"); }
}
partial class Nested
{
public void Test2() { Console.WriteLine("Test2()"); }
}
partial class Nested
{
public void Test3() { Console.WriteLine("Test3()"); }
}
class Program
{
static void Main(string[] args)
{
Nested nested = new Nested();
nested.Test();
nested.Test2();
nested.Test3();
}
}
}
14. 중첩 클래스(Nested Class)
- 클래스 내에 또 클래스가 정의 된 것.
- 내부에 쓰인 클래스는 접근 지정자가 명시되어 있지 않으면 'private'로 지정된다.
15. NULL 조건 연산자
- 조건문을 통한 null 조건 검사가 아닌 연산자를 이용해 편리함을 증대시킴.
- ?.
> 멤버에 접근하기 전 체크
- ?[]
> 인데스 작업을 수행하기 전에 체크
using System;
namespace Example
{
class Program
{
static void Main(string[] args)
{
string result = "string";
if(result != null)
{
// to do
}
}
}
}
- 위와 같은 코드를 아래 처럼 작성할 수 있다.
using System;
namespace Example
{
class Program
{
static void Main(string[] args)
{
string result = "string";
result?.Substring(0, 2);
}
}
}
- 만약 null이라면 '?' 연산자 뒤의 내용은 실행하지 않고 다음 문장으로 넘어간다.
16. 문자열 보간
- 기존에는 String.Format()과 같은 메서드를 사용하여 형식화된 문자열을 출력할 수 있었으나,
문자열 보간을 사용하면 기존의 방법보다 더 읽기 쉽고 편리하게 형식화된 문자열을 만들 수 있다.
string name = "마크";
var date = DateTime.Now;
// 복합 형식 지정(Composite formatting):
Console.WriteLine("안녕, {0}! 오늘은 {1}, {2:HH:mm}이야.", name, date.DayOfWeek, date);
// 문자열 보간(String interpolation):
Console.WriteLine($"안녕, {name}! 오늘은 {date.DayOfWeek}, {date:HH:mm}이야.");
17. 인덱스 초기자
- Dictionary 객체를 인덱스를 통해 초기화 할 수 있다.
private Dictionary webErrors = new Dictionary
{
[404] = "Page not Found",
[302] = "Page moved, but left a forwarding address.",
[500] = "The web server can't come out to play today."
};
18. nameof 연산자
- 변수나 자료형, 멤버의 이름에 해당하는 문자열을 가져오는 데 사용한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var localTime = DateTime.Now.ToLocalTime();
Console.WriteLine(nameof(localTime)); // "localTime"
Console.WriteLine(nameof(args)); // "args"
Console.WriteLine(nameof(System.IO)); // "IO"
Console.WriteLine(nameof(Main)); // "Main"
Console.WriteLine(nameof(Program)); // "Program"
}
}
}
19. catch/finally 에서 await 사용try
- 비동기적으로 예외를 기록하거나, 마지막으로 자원을 해제하는 등의 작업에서 유용하게 사용될 수 있다.
try
{
await OperationThatMayThrowAsync();
}
catch (ExpectedException ex)
{
await MyLogger.LogAsync(ex);
}
20. out 변수
- 'out' 키워드를 사용하면 참조를 통해 인수를 전달할 수 있다. (초기화할 필요 없다)
(ref의 경우에는 변수를 전달하기 전 초기화 해야한다. 즉, 호출하는 측에서 반드시 값을 할당해야 한다.)
- out과 ref는 모두 Call By Reference를 위한 키워드 이다.
차이점은 아래와 같다.
1) out으로 지정된 지정된 인자에 넘길 변수는 초기화하지 않아도 된다.
(초기화해도 out 인자를 받는 메서드에서 그 값을 사용할 수 없음)
2) out으로 지정된 인자를 받는 메서드는 반드시 변수에 값을 넣어서 반환해야 한다.
using System;
namespace ConsoleApp
{
class Program
{
public static void SumAndSub(ref int a, out int sub, int amount)
{
sub = a - amount;
a += amount;
}
static void Main(string[] args)
{
int a = 30;
SumAndSub(ref a, out int sub, 4);
Console.WriteLine("a : " + a + " sub : " + sub);
}
}
}
21. TryParse
- 각 기본 타입에 TryParse라는 메서드를 제공하는데, 이 메서드는 변환이 성공했는지 여부를 true/false로 반환하고
성공하면 out을 지정된 result 변수에 값을 반환한다.
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
string str = "1234";
if (int.TryParse(str, out int a))
{
// TryParse(str, out _) : 변환 값이 필요 없을 경우
Console.WriteLine("string to int 변환 성공 : " + a);
}
else
{
Console.WriteLine("ERROR !");
}
}
}
}
'Language > C#' 카테고리의 다른 글
[C#] 박싱(Boxing)과 언박싱(Unboxing) (0) | 2020.12.23 |
---|---|
[C#] const 와 readonly (0) | 2020.12.23 |
[C#, 공통] 변수 및 함수 표기 방식 (0) | 2020.12.23 |
[C#] struct, class의 참조 형식 (0) | 2020.12.23 |
[C#] 튜플의 사용 (0) | 2020.12.17 |