2012-12-11 67 views
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#標準的另一部分)

任何猜測如何克服這個或我完全卡住?

+2

這個問題有點混亂,因爲它代表。你說你「我需要在運行時檢測是否可以將它轉換爲'Some '」。那將會是'x,如某些'。所以大概你的意思是別的? –

+0

轉換不是微不足道的,因爲我們正在處理協變類型。通常可能無法實現。 – bradgonesurfing

回答

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; 

動態關鍵字是解開運行時類型的魔法。

+0

其實上面的代碼不太適用。看起來,通用函數的動態使用給出了隨機結果。有時它會通知類型,有時會返回Maybe 。我已經改變了我的代碼來使用反射來對動態類型進行具體化,而不是使用泛型 – bradgonesurfing