1

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# 标准的一部分)定义隐式转换,而 Some 是一个接口。有些必须是使其协变的接口(C# 标准的另一部分)

关于如何克服这个问题的任何猜测还是我完全被困住了?

4

1 回答 1

0

诀窍是具体化 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;
    }

一旦我的 Maybe 都被具体化了,我就可以进行正常的铸造了。

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;

动态关键字是解开运行时类型的魔法。

于 2012-12-11T14:40:19.103 回答