c# – 为什么一个可空的序列的Linq-to-Objects总和本身可以为空?

c# – 为什么一个可空的序列的Linq-to-Objects总和本身可以为空?,第1张

概述像往常一样,int?表示System.Nullable< int> (或System.Nullable`1 [System.Int32]). 假设你有一个内存中的IEnumerable< int?> (例如List< int?>例如),让我们称之为seq;那么你可以找到它的和: var seqSum = seq.Sum(); 当然,这是扩展方法重载int? IEnumerable<int?>.Su 像往常一样,int?表示System.Nullable< int> (或System.Nullable`1 [system.int32]).

假设你有一个内存中的IEnumerable< int?> (例如List< int?>例如),让我们称之为seq;那么你可以找到它的和:

var seqSum = seq.Sum();

当然,这是扩展方法重载int? IEnumerable<int?>.Sum() (documentation),这是System.linq.Enumerable上的静态方法.

但是,该方法从不返回null,所以为什么返回类型被声明为Nullable?即使在seq是空集合的情况下,或更一般地,集合的所有元素都是类型为int的空值,则所述的Sum方法仍然返回零,而不是null.

这从文档中可以看出,也可以来自System.Core.dll源代码:

public static int? Sum(this IEnumerable<int?> source) {     if (source == null) throw Error.ArgumentNull("source");     int sum = 0;     checked {         foreach (int? v in source) {             if (v != null) sum += v.GetValueOrDefault();         }     }     return sum; }

请注意,只有一个返回语句,其表达式和具有int类型(然后将隐式地通过换行转换为int?).

总是包装返回值似乎很浪费. (如果需要的话,呼叫者可以总是在他身边隐含地进行包装)

此外,这种返回类型可能会导致调用者编写代码,如if(!seqSum.HasValue){/ *逻辑来处理这个* /},这实际上是不可达到的(C#编译器不知道的事实).

那么为什么这个返回参数不会简单地声明为int,不能为空?

我想知道是否有与int? IQueryable<int?>.Sum()(在System.linq.queryable类中)具有相同返回类型的任何好处.如果有liNQ提供程序(也许liNQ to sql?)实现它,后一种方法在实践中可能返回null.

解决方法 几个意见都提到,这不是真正的问题(或者只是基于没有官方回应的意见).我不会争辩然而,仍然可以对可用代码进行分析,并形成一个足够强大的理论.我只是说这是一个现有的MS模式.

如果您查看System.linq.Enumerable的其余部分,特别是数学相关函数,您将开始看到一种具有返回与输入参数相同类型的趋势的模式,除非返回值具有特定的原因不同的类型

请参阅以下功能:

MAX():

public static int Max(this IEnumerable<int> source);public static int? Max(this IEnumerable<int?> source);public static long Max(this IEnumerable<long> source);public static long? Max(this IEnumerable<long?> source);

MIN():

public static int Min(this IEnumerable<int> source);public static int? Min(this IEnumerable<int?> source);public static long Min(this IEnumerable<long> source);public static long? Min(this IEnumerable<long?> source);

和():

public static int Sum(this IEnumerable<int> source);public static int? Sum(this IEnumerable<int?> source);public static long Sum(this IEnumerable<long> source);public static long? Sum(this IEnumerable<long?> source);

对于规则的例外,请查看平均值…

public static double Average(this IEnumerable<int> source);public static double? Average(this IEnumerable<int?> source);

你可以看到它仍然保留了Nullable T类型,但返回类型必须被更改为合适的类型,以支持平均整数一起产生的结果.

当您进一步了解Average时,您会看到以下内容:

public static float Average(this IEnumerable<float> source);public static float? Average(this IEnumerable<float?> source);

再次,回到与原始传入类型返回相同类型的默认模式.

现在我们在这里看到这个模式,我们来看看我们是否看到其他地方,让我们来看看System.Math,因为我们在这个问题上.

再次,这里我们看到使用相同返回类型的相同模式:

public static int Abs(int value);public static long Abs(long value);public static int Max(int val1,int val2);public static long Max(long val1,long val2);

我会再提一次,这是相当于一个“意见回答”.我已经看过了,可能在这是为MS备份我的分析语言模式暗示任何MS最佳做法或语言规范信息,但我无法找到任何东西.话虽如此,如果您查看.Net核心库中的各种位置,特别是System.Collections.Generic命名空间,您将看到除非有特定的原因,否则返回类型与集合类型相匹配.

我认为没有理由将这个规则从Nullable< T>类型.

总结

以上是内存溢出为你收集整理的c# – 为什么一个可空的序列的Linq-to-Objects总和本身可以为空?全部内容,希望文章能够帮你解决c# – 为什么一个可空的序列的Linq-to-Objects总和本身可以为空?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1236358.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存