我使用自定义Maybe.cs
解决方案
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
namespace FunctionalExtensions.Specs
{
[Microsoft.VisualStudio.TestTools.UnitTesting.TestClass]
public class TestMaybe
{
class Base { }
class A : Base { }
class B : Base { }
[Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
public void TestCovariance()
{
A a = new A();
Maybe<A> ma = a.ToMaybe();
Maybe<A> maa;
Base b = a;
Maybe<Base> mb = ma;
Maybe<Base> mbb = b.ToMaybe();
// This works
(mb is Some<A>).Should().BeTrue ();
maa = (Some<A>)(mb as object);
// This doesn't
(mbb is Some<A>).Should().BeTrue ();
maa = (Some<A>)(mbb as object);
}
}
}
Maybe.cs
实施位于Maybe Implementation in C# — Gist,有点长,可以粘贴到问题中。基本上,我有一个
object
我需要在运行时检测是否可以将其转换为
Some<A>
但请注意,这需要隐式演员才能工作。我的猜测是,我不知道我无法定义接口的隐式转换(c#标准的一部分),有些是接口。有些必须是一个接口来实现它 协变(C#标准的另一部分)
有关如何克服这个或我完全陷入困境的任何猜测?
答案 0 :(得分:0)
诀窍是Reify the Maybe类。
public static Maybe<T> Reify<T>(this Maybe<T> This)
{
if (!This.IsSome())
{
return This;
}
dynamic v = This.Value();
var r = ToMaybe(v);
return r;
}
一旦我的可能性全部具体化,那么我就可以进行正常的施法。
A a = new A();
Base b = a;
Maybe<Base> m = b.ToMaybe();
Maybe<Base> mr = m.Reify();
Maybe<A> ma;
// Will pass
ma = (Maybe<A>) mr;
// Will fail
ma = (Maybe<A>) m;
动态关键字是解开运行时类型的神奇之处。