簡體   English   中英

比較可空值列表

[英]Compare List of Nullable Values

我有以下方法來檢查values1是否超過values2

Boolean CrossAbove<T>(IList<T> values1, IList<T> values2) where T : IComparable {

  return values1[values1.Count - 2].CompareTo(values2[values2.Count - 2]) < 0 && values1.Last().CompareTo(values2.Last()) > 0;

}

所以我可能會使用類似的東西:

List<Decimal> values1 = getValues1();
List<Decimal> values2 = getValues2();

Boolean result = CrossAbove(values1, values2);

但我需要傳遞可為空的值。 例如,使用Decimal? values1

List<Decimal?> values1 = getValues1();
List<Decimal> values2 = getValues2();

Boolean result = CrossAbove(values1, values2);

當比較並且其中一個值為空時,則返回 false ...

如何更改CrossAbove方法以允許這樣做?

更新

我最終得到了以下內容,它允許將一個參數用作可為空的,而將另一個參數用作不可為空的。 或者兩者都可以為空或不可為空:

Boolean CrossAbove<T>(IList<Nullable<T>> values1, IList<Nullable<T>> values2) where T : struct, IComparable {

  if (values1[values1.Count - 2] == null || values1.Last() == null || values2[values1.Count - 2] == null || values2.Last() == null)
    return false;

  return values1[values1.Count - 2].Value.CompareTo(values2[values2.Count - 2].Value) < 0 && values1.Last().Value.CompareTo(values2.Last().Value) > 0;

} 

Boolean CrossAbove<T>(IList<Nullable<T>> values1, IList<T> values2) where T : struct, IComparable => CrossAbove(values1, values2.Select(x => new Nullable<T>(x)).ToList());

Boolean CrossAbove<T>(IList<T> values1, IList<Nullable<T>> values2) where T : struct, IComparable => CrossAbove(values1.Select(x => new Nullable<T>(x)).ToList(), values2);

Boolean CrossAbove<T>(IList<T> values1, IList<T> values2) where T : struct, IComparable => CrossAbove(values1.Select(x => new Nullable<T>(x)).ToList(), values2.Select(x => new Nullable<T>(x)).ToList());

我找不到更好的方法來做到這一點並滿足要求。

有嗎?

您可以修改您的方法以接收比較邏輯,例如:

bool CrossAbove<T>(IList<T> values1, IList<T> values2, Func<T, T, int> compare)
{
     return compare(values1[values1.Count - 2], values2[values2.Count - 2]) < 0 && compare(values1.Last(), values2.Last()) > 0;
}

然后,對於您的第一個示例,它將是:

CrossAbove(values1, values2, decimal.Compare);

對於您的List<decimal?>示例調用,您可以使用如下compare調用您的方法:

CrossAbove(values1, values2, (v1, v2) => {
    if (v1.HasValue && v2.HasValue) {
       return v1.Value.CompareTo(v2.Value);
    }
    return v1 == null && v2 == null;
});

請注意,兩個列表都必須是Nullable<decimal> 希望能幫助到你。

更新:我將在兩個類型參數上實現CrossAbove泛型並繼續接收比較委托:

bool CrossAbove<T1, T2>(IList<T1> values1, IList<T2> values2, Func<T1, T2, int> compare)

在調用CrossAbove您將知道T1T2具體類型是什么,並且您可以傳遞正確的比較委托。 這是我要走的路,我認為它更短。 一個decimaldecimal?的例子decimal? 將是:

// Params: values1: List<decimal>, values2: List<decimal?>
CrossAbove(values1, values2, (x,y) => {
    if (y.HasValue) { return x.CompareTo(y.Value);}
    // Either give 1 or -1 depending on your logic.
    return 1;
});

你可以像這樣使用Nullable.Compare<T>

Boolean CrossAbove<T>(IList<T?> values1, IList<T?> values2) where T : struct
{
    return 
        !values1.Reverse().Take(2).Any(x => !x.HasValue) &&
        !values2.Reverse().Take(2).Any(x => !x.HasValue) &&
        Nullable.Compare<T>(values1[values1.Count - 2],values2[values2.Count - 2]) < 0 
        && Nullable.Compare<T>(values1.Last(), values2.Last()) > 0;
}

但是,它基於此處描述的Nullable比較進行比較這與您的預期不同。 但是你可以做一些你想要的修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM