我在Github上使用了一个名为OneOf的lib。
基本上你有一种类型可以是多种类型之一,但是以静态安全的方式。
以下是我试图实现的一个例子
我输入了A<T1, T2, T3, T4>
,输入了B<T1, T2, T3>
,我想要&#34; flapmap&#34;键入A到类型A.因为类型A可以接受来自B的任何单个T,所以它应该是可能的。
编译器强制我从B中提取每个T,然后将其分配给A,正如您在下面的愚蠢的x => x
lambdas所看到的那样。
我也不想结束像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 :(得分:0)
扩展方法可能是一种方式。
一个例子,就在我的脑海中,转换3到4种类型:
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);
}
}
它不是特别漂亮,但它应该保持你的代码相对干净。