2016-09-08 5 views
2

저는 Github off lib를 사용하여 OneOf라고합니다.평면도 식별 유니온

기본적으로 여러 유형 중 하나 일 수 있지만 정적으로 안전한 방식으로 사용할 수 있습니다.

다음은 내가 달성하고자하는 것의 예입니다.
유형 A<T1, T2, T3, T4>이 있고 유형이 B<T1, T2, T3> 인 경우, 유형 B를 유형 A로 "플랩 맵"하고 싶습니다. 유형 A는 B에서 임의의 단일 T를 허용 할 수 있으므로 가능해야합니다.

컴파일러는 아래의 바보 같은 x => x에서 볼 수 있듯이 B에서 A를 할당하기 전에 각 T를 추출해야합니다.

A<B<T1, T2, T3>, T4>과 같은 것으로 끝내고 싶지 않습니다.
누구나 기본적으로 이러한 OneOf 유형의 SelectMany를 생각할 수 있습니까?

using OneOf; 
using System; 
using System.IO; 

namespace ScratchPad 
{ 
    class Program 
    { 
     struct BadRequest { } 
     struct Error { } 
     struct NotFound { } 

     static void Main(string[] arg) 
     { 
      string result = GetFile(@"c:\data\foo.txt").Match(
       text => text, 
       badRequest => "filepath cannot be null", 
       notFound => "filepath does not exist", 
       error => "an error occurred" 
      ); 

      Console.WriteLine(result); 
     } 

     static OneOf<string, BadRequest, NotFound, Error> GetFile(string filepath) 
     { 
      OneOf<string, BadRequest, NotFound, Error> response = new BadRequest(); 

      if (filepath != null) 
      { 
       // How can I make the type from ReadText() automatically convert to the type of the response local variable, without having to write these silly lambda? 
       response = ReadText(filepath).Match<OneOf<string, BadRequest, NotFound, Error>>(x => x, x => x, x => x); 
      } 

      return response; 
     } 

     static OneOf<string, NotFound, Error> ReadText(string filepath) 
     { 
      OneOf<string, NotFound, Error> response = new NotFound(); 

      try 
      { 
       if (File.Exists(filepath)) 
       { 
        response = File.ReadAllText(filepath); 
       } 
      } 
      catch 
      { 
       response = new Error(); 
      } 

      return response; 
     } 
    } 
} 

답변

0

확장 메서드가 될 수 있습니다.

public static class OneOfExtensions 
{ 
    public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T2, T3> oneOf) 
    { 
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x); 
    } 

    public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T2, T4> oneOf) 
    { 
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x); 
    } 

    public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T1, T3, T4> oneOf) 
    { 
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x); 
    } 

    public static OneOf<T1, T2, T3, T4> ConvertOneOf<T1, T2, T3, T4>(this OneOf<T2, T3, T4> oneOf) 
    { 
    return oneOf.Match<OneOf<T1, T2, T3, T4>>(x => x, x => x, x=> x); 
    } 
} 

그것은 특히 꽤 아니지만, 비교적 깨끗한 코드를 유지해야한다 : 3 ~ 4 종류의 변환 내 머리 밖으로

예,,.