728x90
반응형
▶ Program.cs
using System;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
Console.WriteLine
(
"01".Match()
.AddCase(s => s == "01", "홍길동")
.AddCase(s => s == "02", "김철수")
.AddCase(s => s == "03", "최영희")
.AddElseCase("무명씨")
.Execute()
);
}
#endregion
}
}
▶ IncompletePatternMatchException.cs
using System;
namespace TestProject
{
/// <summary>
/// 불완전 패턴 매치 예외
/// </summary>
public class IncompletePatternMatchException : Exception
{
}
}
▶ PatternMatchValue.cs
using System;
using System.Collections.Generic;
namespace TestProject
{
/// <summary>
/// 패턴 매치 값
/// </summary>
/// <typeparam name="TSource">소스 타입</typeparam>
/// <typeparam name="TResult">결과 타입</typeparam>
public class PatternMatchValue<TSource, TResult>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 패턴 매치 케이스 - PatternMatchCase
/// <summary>
/// 패턴 매치 케이스
/// </summary>
private struct PatternMatchCase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 판정 대리자
/// </summary>
public Predicate<TSource> Predicate;
/// <summary>
/// 결과 함수
/// </summary>
public Func<TSource, TResult> ResultFunction;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 소스
/// </summary>
private readonly TSource source;
/// <summary>
/// 패턴 매치 케이스 리스트
/// </summary>
private readonly IList<PatternMatchCase> list = new List<PatternMatchCase>();
/// <summary>
/// ELSE 케이스 함수
/// </summary>
private Func<TSource, TResult> elseCaseFunction;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - PatternMatchValue(source)
/// <summary>
/// 생성자
/// </summary>
/// <param name="source">소스</param>
public PatternMatchValue(TSource source)
{
this.source = source;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 케이스 추가하기 - AddCase(predicate, result)
/// <summary>
/// 케이스 추가하기
/// </summary>
/// <param name="predicate">판정 대리자</param>
/// <param name="result">결과</param>
/// <returns>패턴 매치 값</returns>
public PatternMatchValue<TSource, TResult> AddCase(Predicate<TSource> predicate, TResult result)
{
return AddCase(predicate, x => result);
}
#endregion
#region 케이스 추가하기 - AddCase(predicate, resultFunction)
/// <summary>
/// 케이스 추가하기
/// </summary>
/// <param name="predicate">판정 대리자</param>
/// <param name="resultFunction">결과 함수</param>
/// <returns>패턴 매치 값</returns>
public PatternMatchValue<TSource, TResult> AddCase
(
Predicate<TSource> predicate,
Func<TSource, TResult> resultFunction
)
{
list.Add
(
new PatternMatchCase
{
Predicate = predicate,
ResultFunction = resultFunction
}
);
return this;
}
#endregion
#region ELSE 케이스 추가하기 - AddElseCase(result)
/// <summary>
/// ELSE 케이스 추가하기
/// </summary>
/// <param name="result">결과</param>
/// <returns>패턴 매치 값</returns>
public PatternMatchValue<TSource, TResult> AddElseCase(TResult result)
{
return AddElseCase(x => result);
}
#endregion
#region ELSE 케이스 추가하기 - AddElseCase(resultFunction)
/// <summary>
/// ELSE 케이스 추가하기
/// </summary>
/// <param name="resultFunction">결과 함수</param>
/// <returns>패턴 매치 값</returns>
public PatternMatchValue<TSource, TResult> AddElseCase(Func<TSource, TResult> resultFunction)
{
if(this.elseCaseFunction != null)
{
throw new InvalidOperationException("Cannot have multiple else cases");
}
this.elseCaseFunction = resultFunction;
return this;
}
#endregion
#region 실행하기 - Execute()
/// <summary>
/// 실행하기
/// </summary>
/// <returns>결과</returns>
public TResult Execute()
{
if(this.elseCaseFunction != null)
{
AddCase(x => true, this.elseCaseFunction);
this.elseCaseFunction = null;
}
foreach(PatternMatchCase @case in this.list)
{
if(@case.Predicate(source))
{
return @case.ResultFunction(source);
}
}
throw new IncompletePatternMatchException();
}
#endregion
}
}
▶ PatternMatchContext.cs
using System;
namespace TestProject
{
/// <summary>
/// 패턴 매치 컨텍스트
/// </summary>
/// <typeparam name="TSource">소스 타입</typeparam>
public class PatternMatchContext<TSource>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 소스
/// </summary>
private readonly TSource source;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - PatternMatchContext(source)
/// <summary>
/// 생성자
/// </summary>
/// <param name="source">소스</param>
public PatternMatchContext(TSource source)
{
this.source = source;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 케이스 추가하기 - AddCase<TResult>(predicate, result)
/// <summary>
/// 케이스 추가하기
/// </summary>
/// <typeparam name="TResult">결과 타입</typeparam>
/// <param name="predicate">판정 대리자</param>
/// <param name="result">결과</param>
/// <returns>패턴 매치 값</returns>
public PatternMatchValue<TSource, TResult> AddCase<TResult>(Predicate<TSource> predicate, TResult result)
{
return new PatternMatchValue<TSource, TResult>(source).AddCase(predicate, result);
}
#endregion
}
}
▶ PatternMatchExtension.cs
namespace TestProject
{
/// <summary>
/// 패턴 매치 확장
/// </summary>
public static class PatternMatchExtension
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 매치하기 - Match(value)
/// <summary>
/// 매치하기
/// </summary>
/// <typeparam name="TSource">소스 타입</typeparam>
/// <param name="source">소스</param>
/// <returns>패턴 매치 컨텍스트</returns>
public static PatternMatchContext<TSource> Match<TSource>(this TSource source)
{
return new PatternMatchContext<TSource>(source);
}
#endregion
}
}
728x90
반응형
'C# > Common' 카테고리의 다른 글
[C#/COMMON] Lazy<T> 클래스 : 변환 함수를 사용해 지연 객체 변환하기 (0) | 2019.11.24 |
---|---|
[C#/COMMON] 변환 함수를 사용해 객체 변환하기 (0) | 2019.11.24 |
[C#/COMMON] 변환 함수를 사용해 NULL 가능형 구조체 값 변환하기 (0) | 2019.11.24 |
[C#/COMMON] 변환 함수를 사용해 NULL 가능형 구조체 값 변환하기 (0) | 2019.11.24 |
[C#/COMMON] yield return 키워드를 사용해 열거 가능형 구하기 (0) | 2019.11.24 |
[C#/COMMON] switch ... case ... 구문에 대응하는 함수형 사용하기 (0) | 2019.11.24 |
[C#/COMMON] 16진수 문자열에서 정수 값 구하기 (0) | 2019.11.24 |
[C#/COMMON] Lazy<T> 클래스 : 지연 초기화(lazy initialization) 사용하기 (0) | 2019.11.23 |
[C#/COMMON] 지연 열거를 사용해 피보나치 수열 구하기 (0) | 2019.11.23 |
[C#/COMMON] 간접 재귀를 사용해 홀짝 여부 구하기 (0) | 2019.11.23 |
[C#/COMMON] 연속 전달형의 꼬리 재귀를 사용해 팩토리얼 구하기 (0) | 2019.11.23 |
댓글을 달아 주세요