代码之家  ›  专栏  ›  技术社区  ›  John Feminella

如何让C编译器自动推断这些类型参数?

  •  1
  • John Feminella  · 技术社区  · 16 年前

    我有一些代码如下所示。首先我有一些域类和一些特殊的比较器。

    public class Fruit {
      public int Calories { get; set; }
      public string Name { get; set; }
    }
    
    public class FruitEqualityComparer : IEqualityComparer<Fruit> {
      // ...
    }
    
    // A basket is just a group of Fruits.
    public class BasketEqualityComparer : IEqualityComparer<IEnumerable<Fruit>> {
      // ...
    }
    

    接下来,我有一个名为 ConstraintChecker . 它有一个简单的 BaseEquals 确保考虑一些简单基本情况的方法:

    public static class ConstraintChecker {
      public static bool BaseEquals(T lhs, T rhs) {
        bool sameObject = l == r;
        bool leftNull = l == null;
        bool rightNull = r == null;
    
        return sameObject && !leftNull && !rightNull;
      }
    

    还有一个 SemanticEquals 方法只是一个

      public static bool SemanticEquals<T>(
        T lhs, T rhs, Func<T, T, bool> f) {
        return BaseEquals(lhs, rhs) && f(lhs, rhs);
      }
    

    最后是一个 SemanticSequenceEquals 接受两个 IEnumerable<T> 要比较的实例,以及一个IEqualityComparer实例,该实例将通过 Enumerable.SequenceEquals .

      public static bool SemanticSequenceEquals<T, U, V>(U lhs,
                                                         U rhs,
                                                         V comparator)
        where U : IEnumerable<T>
        where V : IEqualityComparer<T> {
        return SemanticEquals(lhs, rhs, (l, r) => lhs.SequenceEqual(rhs, comparator));
      }
    } // end of ConstraintChecker
    

    重点 你不需要定义两个比较器,只要你想比较两者 T 实例;现在您只需指定 IEqualityComparer<T> 语义序列等于 . 所以我可以摆脱篮球平等比较班,这将是很好的。

    但有个问题。当您调用SemanticSequenceEquals时,C编译器无法找出所涉及的类型:

    // Error! Compiler can't infer the type parameters.
    return ConstraintChecker.SemanticSequenceEquals(lhs, rhs,
      new FruitEqualityComparer());
    

    如果我显式地指定它们,它就会起作用:

    return ConstraintChecker.SemanticSequenceEquals<Fruit, IEnumerable<Fruit>,
      IEqualityComparer<Fruit>> (lhs, rhs, new FruitEqualityComparer());
    

    显然,这是一个巨大的麻烦,它不是很干燥。我可以在这里修改什么,这样就不必显式地编写类型参数了?

    2 回复  |  直到 16 年前
        1
  •  2
  •   juharr    16 年前

    试着只指定T而不指定U和V。

    public static bool SemanticSequenceEquals<T>(
        IEnumerable<T> lhs, 
        IEnumerable<T> rhs, 
        IEqualityComparer<T> comparator)
    {
        return SemanticEquals(lhs, rhs, (l, r) => lhs.SequenceEqual(rhs, comparator));
    }
    
        2
  •  1
  •   Gary Linscott    16 年前

    public static bool SemanticSequenceEquals<T>(IEnumerable<T> lhs, IEnumerable<T> rhs, IEqualityComparer<T> comparator)
    {
        return SemanticEquals(lhs, rhs, (l, r) => lhs.SequenceEqual(rhs, comparator));
    }
    
    List<Fruit> a, b;
    return ConstraintChecker.SemanticSequenceEquals(a, b, new FruitEqualityComparer());
    
    推荐文章