[ yield return/break ]
- "yield return", "yield break" 예약어를 이용하면 기존의 IEnuerable, IEnumerator 인터페이스를 이용해 구현했던 열거 기능을 쉽게 구현할 수 있다.
- IEnumerable을 이용해서 아래와 같이 무한 집합을 구현할 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
namespace ConsoleApp1
{
// 1부터 자연수를 무한하게 출력(int 범위)
public class NaturalNumber : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
return new NaturalNumberEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return new NaturalNumberEnumerator();
}
}
public class NaturalNumberEnumerator : IEnumerator<int>
{
int _current;
public int Current
{
get { return _current; }
}
object IEnumerator.Current
{
get { return _current; }
}
public void Dispose() { }
public bool MoveNext()
{
_current++;
return true;
}
public void Reset()
{
_current = 0;
}
}
class Program
{
static void Main(string[] args)
{
NaturalNumber number = new NaturalNumber();
foreach(int n in number)
{
Console.WriteLine(n);
}
}
}
}
- 구현이 번거로운데, yield를 이용해 다음과 같이 간단하게 바꿀 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
namespace ConsoleApp1
{
// 1부터 자연수를 무한하게 출력(int 범위)
public class YieldNaturalNumber
{
public static IEnumerable<int> Next()
{
int _start = 0;
while(true)
{
_start++;
yield return _start;
}
}
}
class Program
{
static void Main(string[] args)
{
foreach(int n in YieldNaturalNumber.Next())
{
Console.WriteLine(n);
}
}
}
}
- Next 메서드가 호출되면 yield return에서 값이 반환되면서 메서드가 중단된다. 다음에 다시 메서드가 호출되면 yield return이 실행된 코드의 다음 줄부터 실행을 재개한다고 이해하면 된다. (실제 내부 구현은 원래 예제와 유사하게 치환됨)
[ Partial class ]
- partial 예약어를 클래스에 적용하면 클래스의 소스코드를 2개 이상으로 나눌 수 있다.
- 한 파일에 있어도 되고, 다른 파일로 나눠도 되지만 반드시 같은 프로젝트에서 컴파일 해야 한다. C# 컴파일러는 빌드 시에 같은 프로젝트에 있는 partial 클래스를 하나로 모아 단일 클래스로 빌드한다.
using System;
namespace ConsoleApp1
{
partial class Person
{
string _name;
public string Name { get { return _name; } set { _name = value; } }
}
partial class Person
{
int _age;
public int Age { get { return _age; } set { _age = value; } }
}
}
[ nullable 형식 ]
- System.Nullable<T> 구조체를 의미하며 일반적인 값 형식에 대해서 null 표현이 가능하게 하는 역할을 한다.
(bool type의 결혼 여부 변수에서 입력을 아예 안한다면??)
- Nullable<bool>을 bool?로 축약하여 쓸 수도 있다.
using System;
namespace ConsoleApp1
{
public class SiteMember
{
bool _getMarried;
public bool GetMarried
{
get { return _getMarried; }
set { _getMarried = value; }
}
}
public class SiteMemberNullAble
{
Nullable<bool> _getMarried;
public Nullable<bool> GetMarried
{
get { return _getMarried; }
set { _getMarried = value; }
}
}
public class SiteMemberNullAble2
{
bool? _getMarried; // Nullable<bool>의 축약형
public bool? GetMarried
{
get { return _getMarried; }
set { _getMarried = value; }
}
}
class Program
{
static void Main(string[] args)
{
SiteMemberNullAble m1 = new SiteMemberNullAble();
Console.WriteLine(m1.GetMarried == null); // true
Console.WriteLine(m1.GetMarried.HasValue);
m1.GetMarried = true;
Console.WriteLine(m1.GetMarried == null); // false
Console.WriteLine(m1.GetMarried.HasValue);
}
}
}
[ 익명 메서드 ]
- 델리게이트에 전달되는 메서드가 일회성으로만 필요할 때 편의상 사용된다.
- 실제 컴파일 될 때는 중복되지 않을 특별한 문자열을 하나 생성해 메서드를 만든다.
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(delegate (object obj)
{
Console.WriteLine("ThreadFunc in anonymous method called!");
});
thread.Start();
thread.Join();
}
}
}
- 익명 메서드를 델리게이트 타입의 변수에 담아 재사용하는 것도 가능하다.
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
delegate int? MyDivide(int a, int b);
static void Main(string[] args)
{
MyDivide myFunc = delegate (int a, int b)
{
if (b == 0) return null;
return a / b;
};
Console.WriteLine("10 / 2 == " + myFunc(10, 2));
Console.WriteLine("10 / 0 == " + myFunc(10, 0)); // null
}
}
}
[ 정적 클래스 ]
- static class로 정의하여 static 멤버만 내부에 포함할 수 있다. 인스턴스 멤버를 포함할 필요가 없다는 사실을 명시하기 위해서 사용한 것이다.
- 예시로는 System.Math 타입이 있다.
- 출처 : 시작하세요! C# 7.1 프로그래밍(위키북스), 정성태님 저
'Programming > C#' 카테고리의 다른 글
C# 3.0 변경점(2) - 람다 식 (0) | 2019.04.04 |
---|---|
C# 3.0 변경점(1) - var, 자동 구현 속성, 객체/컬렉션 초기화, 익명 타입, 확장 메서드 (0) | 2019.04.03 |
C# 2.0 변경점(1) - 제네릭스(Generics), ?? 연산자 (0) | 2019.03.31 |
리플렉션(Reflection) (0) | 2019.03.12 |
MSSQL Database 연동(2) (0) | 2019.03.11 |