첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ switch ... case ... 구문에 대응하는 함수형 사용하기

------------------------------------------------------------------------------------------------------------------------

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

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요