【问题标题】:Should pattern matching in C# 7 work with generics?C# 7 中的模式匹配应该与泛型一起使用吗?
【发布时间】:2017-06-20 10:27:22
【问题描述】:

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

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
          )
        {
            ...
        }


}

但会导致以下错误。

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

当然,我可以只使用typeof(U)typeof(T) 来进行测试,但我认为上面应该真的有效。为什么不呢?

【问题讨论】:

    标签: c# generics pattern-matching


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        有一个解决该错误/功能的方法。您可以将 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();
        
        }    
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-26
          • 1970-01-01
          • 2011-10-25
          相关资源
          最近更新 更多