2016-09-08 8 views
2

私はと呼ばれるGithubオフのlibを使用しています。フラットマップ識別ユニオン

基本的には、多くのタイプの1つがありますが、静的に安全な方法です。

以下は私が達成しようとしているものの例です。
タイプA<T1, T2, T3, T4>があり、B<T1, T2, T3>と入力してください。タイプBをタイプAに「フラップマップ」したいと考えています。タイプAはBから1つの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種類を変換するだけで私の頭のうち

たとえば、。