繁体   English   中英

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

[英]How can I make the C# compiler infer these type parameters automatically?

我有一些看起来像下面的代码。 首先,我有一些领域类和一些特殊的比较器。

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方法,它只是BaseEquals检查和您指定的比较器函数。

  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

SemanticSequenceEquals的要点是,无论何时要比较IEnumerable<T>T实例,都不必定义两个比较器。 现在,您只需指定IEqualityComparer<T> ,当您调用SemanticSequenceEquals时,它也将处理列表。 因此,我可以摆脱BasketEqualityComparer类,这很好。

但是有一个问题。 当您调用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());

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

尝试仅指定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));
}

您可以将参数明确输入SemanticSequenceEquals。 这似乎对我来说很好:

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());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM