참고 자료: MS Document
- C#이 생각보다 자료가 많이 없어서 그냥 공식문서 보고 정리하려고 한다.
 
일단은공식문서상의 구조를 따라가려고 하는데 내용은 내 맘대로 써질 예정- 본질이 iOS 개발자라 많이 비교하면서 학습을 진행할 예정이다.
 
- @>--- 이런 기호와 함께 '기울임', '작게' 표시 되면 개인적인 생각이다.- 당연 이건 다른 언어를 했던 사람들이 C# 공부시 그나마 조금 편하라고 만들어 보는거지 아예 코드 짜는 사람이 처음이라면 이해 안될 수 있는다.
 - 이해 안되는건 뒤에 나올 내용이 앞에 나와서 그러는거니까 첨보는 단어면 일단 넘어가면 뒤에 다시 나온다.
 
참조 형식이다.new 연산자를 사용해 클래스의 인스턴스를 명시적으로 만들거나, 다른 곳에서 생성되었을 수 있는 호환되는 형식의 개체를 할당할 때까지 null을 포함한다.인스턴스를 만들 떄 해당 필드와 속성이 유용한 값으로 초기화하는 방법에는 여러 가지가 있다.
모든 .NET 형식에는 디폴트가 있는데 숫자 형식은 0이고 모든 참조 형식은 null이다.
기본값이 올바른 값이 아닌 경우 초기값을 설정 할 수 있다.
public class Container
{
    private int _capacity = 10;
}
호출자가 초기 값을 설정하는 생성자를 정의해 초기 값을 제공하게 요구할 수 있다.
public class Container
{
    private int _capacity;
    public Container(int capacity) => _capacity = capacity;
}
=> : 이게 뭘까?
- 해당 연산자는
 람다(Lamda)식에서 사용되는람다 연산자또는화살표 연산자라고 불린다.람다 식과본문 멤버를 정의할 때 사용한다.1 . 람다식에서의 사용: 람다 연산자
람다식은익명 함수를 표현하는 간결한 방법으로 메서드나 대라지를 정의하지 않고도 함수를 전달할 수 있다.
- 사용방법은
 (입력 매개변수) => 식 또는 문장 블록이런식으로 하며 사용 방법은2가지가 있다.
- 이렇게 표기할때 입력 매개 변수가 없으면
 () => 식 또는 문장 블록으로 표현하면 된다.static void Main(string[] args) { var nums = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; List<int> search = nums.FindAll(x => x % 2 == 0); foreach (int n in search) Console.WriteLine(n); }
- 람다식은 뭔가 함수를 새로 지정해서 해당 동작을 하는 그런 로직을 짜기에는 코드가 길어져 바로바로 확인이 안되거나 진짜 간단 로직 + 1회성인걸 굳이 함수까지 만들 필요 없을때 쓰면 좋을것으로 보인다.
 - 해당 코드 작성은 조금 더 익숙해져야 충분히 가능하겠지만 그런게 아니라면 초콤 문법 상으로 헷갈릴 여지가 있어보인다.
 Func<int,int,int> check = (x,y) => { return x*y; };@>--- 자주 이용할 것 같은 람다식 구현 방법
2 . Expression-bodied member (식 본문 멤버(?))
- 일단 예제 코드를 먼저 봐보자
 public static int Add(int x, int y) => x + y;
- 뭔가 람다식과 비슷한 모습을 보이는것처럼 보이는데 엄밀히 말하면
 완전 다른개념이다.- 이 문법은 메서드, 속성, 생성자, 소멸자 등을 간결하게 표현하기 위해 사용된다.
 - 해당 문법은 메서드나 속성의 본문을 간단한 식(expression)으로 대체하는 문법입니다.
 
- 메서드의
 본문이한 줄로 간단히 표현될 때 =>를 사용해 이를 간결하게 나타낼 수 있습니다.@>--- 이게 뭔뜻이냐면 얘는 메서드라는거다.
그렇다는건, Main 함수 내에서 선언하고 바로 사용하고 메모리 날리고가 안된다는 소리다.정리
- 람다식 = 익명 함수 정의에 사용 + 주로 대리자(delegate)나 LINQ에서 함수형 프로그래밍을 지원하기 위해 활용
 - Expression-bodied member = 간결하게 표현하는 방법으로 주로 코드의 가독성을 높이고 간단한 메서드를 축약할 때 사용
 
@>--- 약간 swift와 obj-C의 클로저나 블록과도 비슷한 느낌으로 보면 이해하기 쉬울것으로 보인다.
클래스 생성과 동시에 초기화 시키기
- 일단 예제 코드를 먼저 작성해보자
 class Program { static void Main(string[] args) { TestClass tcl = new TestClass(); Console.WriteLine(tcl.ReadX()); } } class TestClass { private int x; public TestClass() => x = 3; public int ReadX() => x; }
- 여기서 눈여겨 볼 곳은 TestClas클래스의
 TestClass 메서드이다.
- 사용하는 방법은 매우 간단하다. 몇가지
 조건만 맞다면 애용하게 될 방법이다.
1] 클래스를 코드상에 입력할때는 그 값을 정하지 않는 즉, 동적인 변수가 필요로 할때 해당 변수의 값을 초기화 시킬떄
2] 해당 클래스가 처음 인스턴스로 할당될 때 해당 값이 초기화 되었으면 할때 사용하면 된다.
- 위의 조건들 외에도 여러 조건이 있겠지만 그걸 떠나 그냥 클래스 초기화 할때 쓴다 생각하믄 된다.
 - 사용방법 또한 매우 쉬운데
 public 클래스_이름(매개변수) = {초기화 구문}이런식으로 클래스의이름과 똑같은메서드를 만들어 뒤에 초기화 구문을 넣어주면 된다.- 예시 코드에서는 직접값을 넣어주고 있지만, 클래스 이름 뒤의 매개변수 넣는곳에 매개변수를 삽입해서 클래스 외부에서 변수의 값을 지정해줄 수 도 있다.
 - 그리고
 C# 12에서 나온건데 아래처럼 직접 클래스 명에서 변수 때려서 하는것도 있는데 개인적으로는 전자의 방법을 더 애용할 것 같다.class TestClass(int inx) { private int x = inX; public int ReadX() => x; }
속성에서 required 한정자를 사용하고 호출자가 개체 이니셜라이저를 사용하여 속성의 초기 값을 설정하도록 허용할 수도 있습니다.
- 이 키워드를 사용해서 생성된 변수는! 무조건 초기화 작업을 해야 한다는것을 의미함 new 클래스() 하고 뒤에 {} 이렇게 해서!!
예시 코드는 다음과 같다.
class Program
  {
      static void Main(string[] args)
      {
          TestClass tcl = new TestClass() { y = 3 };
      }
  }
class TestClass
{
    public required int y { get; set; }
}
상속을 완전히 지원한다.sealed로 정의디지 않은 다른 클래스에서 상속할 수 있다.파생을 통해 수행된다.기본,파생을 나눠서 설명을 한다.기본의 경우에는 가장 윗단 즉 트리의 루트 노드 같은 형식을 이야기 한다.파생의 경우에는 기본을 상속하는 모든 형식들을 이야기 한다.파생은 무조건 자식이 아닐 수도 있다. (이 파생을 상속하는 다른 파생이 있으면 부모이자 자식이 되는거니까)public class Sean: Person { ... }클래스의 상속과 인터페이스
- swift와 다르게 C#에서의 클래스는
 하나의상속만 가능하기에 이를 조금이나마 따라하는 작업으로 인터페이스를 사용한다.- 여러 인터페이스를 구현함으로 다중 상속의
 일부기능을흉내낼 수 있다.
중요한 키워드는일부,흉내이다.왜 일부 흉내일까?
상속과 인터페이스로 구현했을때의 코드 차이를 예시로 보여주겠다.
public class Animal { public void Eat() { Console.WriteLine("eating..."); } } public class Dog : Animal { public void NextAction() { Eat(); Console.WriteLine("next..."); } }public interface Bird { void Fly(); } public interface Carnivore { void WantMeat(); } public class Eagle : Animal, Bird, Carnivore { public void Fly() { Console.WriteLine("flying..."); } public void WantMeat() { Console.WriteLine("Want Meat..."); } public void NextAction() { Fly(); Eat(); WantMeat(); Console.WriteLine("next..."); } }상속은 애초에 부모의 모든것을 가져오기에
부모가 구현해둔로직까지 다 가져올 수 있지만인터페이스의 경우에는 그렇다기 보다는 그냥
청사진을 그려주는 역할밖에 못하기에 해당 로직은 선택한 클래스에서 구현을 해줘야 한다.그렇기에 의존성이나 관계도 또는 코드의 이해를 위하는 방법은 둘이 비슷할지 언정 정작 내부 디테일적으로 보게 되면 완벽하게 다른걸 알 수 있다.