需要协变铸造解决方案

时间:2012-12-11 11:30:31

标签: c# casting covariance

我使用自定义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#标准的另一部分)

有关如何克服这个或我完全陷入困境的任何猜测?

1 个答案:

答案 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;

动态关键字是解开运行时类型的神奇之处。

相关问题