簡體   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