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# 標準の一部) からの暗黙的な変換を定義できず、一部がインターフェイスであるという事実に固執していると思います。一部は共変にするためのインターフェースでなければなりません(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;
    }

メイビーがすべて具体化されたら、通常のキャストを実行できます。

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;

dynamic キーワードは、ランタイム タイプをアンラップする魔法です。

于 2012-12-11T14:40:19.103 に答える