C#7中的模式匹配是否应该与泛型一起使用?

时间:2017-06-20 10:27:23

标签: c# generics pattern-matching

我有一个简单的例子,我想使用模式匹配来识别我需要用来在两个通用八度之间执行碰撞测试的算法。我的基本情况是两个八角形的三角形。代码的骨架是。

public class Triangle {
        public static bool 
           Intersects
             ( IReadOnlyList<Triangle> ta
             , IReadOnlyList<Triangle> tb)
        {
             ...
        }
}

public class Octree<T> {

        public bool Intersects<U>(Octree<U> other)
        {
            if (this is Octree<Triangle> ota && other is Octree<Triangle> otb)
            {
                return ota.Intersects( otb, Triangle.Intersects );
            }
            throw new NotImplementedException();

        }

        public bool Intersects<U>
          ( Octree<U> other
          , Func<IReadOnlyList<T>, IReadOnlyList<U>, bool> intersectsLeaves
          )
        {
            ...
        }


}

但导致以下错误。

enter image description here

Error CS8121
An expression of type Octree<T> cannot be handled by a pattern of type
Octree<Triangle>.

当然我可以使用typeof(U)typeof(T)来进行测试,但我认为上述内容确实可行。为什么不呢?

3 个答案:

答案 0 :(得分:2)

C#7.0中的模式匹配要求声明必须存在从左侧类型到右侧类型的显式或隐式转换。

在C#7.1中,规范将被扩展,以便左侧或右侧可以是开放式。

答案 1 :(得分:1)

它是一个错误。看看这个: https://github.com/dotnet/roslyn/issues/16195

答案 2 :(得分:0)

有一个解决bug /功能的工作。您可以将 Try * 模式与内联声明的变量一起使用。

bool TryIs<TU>(object t, out TU u)
{
    if (t is TU uu)
    {
        u = uu;
        return true;
    }
    u = default(TU);
    return false;
}

然后你可以像

一样使用它
public bool Intersects<U>(Octree<U> other)
{
    if ( TryIs<Octree<Triangle>>(out var ota) && TryIs<Octree<Triangle>>(out var otb))
    {
        return ota.Intersects( otb, Triangle.Intersects );
    }
    throw new NotImplementedException();

}