2012-12-11 3 views
1

I 사용자 정의에게 Maybe.cs 구현 Maybe Implementation in C# — Gist에 있고 의문에 붙여 조금 긴 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); 
     } 
    } 
} 

을 사용하여 다음과 같은 코드가 있습니다. 기본적으로, 나는 그러나 이것이 내가 생각하는 일을 암시 적 캐스트가 있어야한다는 사실을 명심해야합니다

Some<A> 

로 변환 할 수 있는지가 실행 시간에 감지 할 필요가

object 

의 인스턴스를 가지고있다. 내 생각 엔 인터페이스 (C# 표준의 일부)에서 암시 적 변환을 정의 할 수 없다는 사실에 집착하고 일부는 인터페이스입니다. 일부는 인터페이스가되어야합니다. 공변 (C# 표준의 다른 부분)

이것을 극복하는 방법에 대한 추측이나 완전히 붙어 있습니까?

답변

0

마술 클래스를 수정하는 것이 트릭입니다.

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; 
    } 

내 어쩌면 모든 후, 나는 peform받는 수 구체화 정상적인 주조 한 번.

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

사실 위의 코드는 제대로 작동하지 않습니다. 일반 함수로 동적 인 사용은 무작위 결과를 얻는 것 같습니다. 때로는 형식을 확인하고 때때로 반환합니다 일 수 있습니다. 제네릭을 사용하는 대신 리플렉션을 사용하여 동적 유형의 구체화를 수행하도록 코드를 변경했습니다. – bradgonesurfing