iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >在NullObject中C#6.0有哪些改进
  • 903
分享到

在NullObject中C#6.0有哪些改进

2023-06-17 06:06:16 903人浏览 泡泡鱼
摘要

今天就跟大家聊聊有关在NullObject中C#6.0有哪些改进,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是空引用异常作为一个敲过代码的码农来说,似乎没有谁没有遇到过Null

今天就跟大家聊聊有关在NullObject中C#6.0有哪些改进,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

什么是空引用异常

作为一个敲过代码的码农来说,似乎没有谁没有遇到过NullReferenceException这 个问题,有些时候当方法内部调用一个属性、方法(委托)时,我们控制这些属性在“外部”的表现(当然某些情况下使用ref关键字除外),所以我们要在方法 的内部去判断属性、委托方法是否为Null来避免可能的、错误使用上带来的空引用异常,这样当我们知道如果对象为Null的话,我们会实现符合我们“预 期”的行为。

解决空引用异常---Check Any Where

这很简单,我只要在需要用的地方检查一下是否为Null就可以了。是的,这非常简单,语义也很清晰,但是当你要重复检查一个对象实体10000万次时,你的代码中将存在10000个如下代码段:

public void Check()         {             if (Person.AlivePerson() != null)             {                 Person.AlivePerson().KeepAlive = true;             }          }

你能容忍这样的行为吗?

If(OK)

Continue;

Else

Close;

应用NullObject设计模式

NullObjectPattern出自forth by Gamma(设计模式4人组),核心内容是:提供一个给定对象的空值代理,空值代理中提供不做任何事情的方法实现。

接下来让我们看看维基百科上的C#实现:

// compile as Console Application, requires C# 3.0 or higher using System; using System.Linq; namespace MyExtensionWithExample {     public static class StringExtensions {          public static int SafeGetLength(this string valueOrNull) {              return (valueOrNull ?? string.Empty).Length;          }     }     public static class Program {         // define some strings         static readonly string[] strings = new [] { "Mr X.", "Katrien Duck", null, "Q" };         // write the total length of all the strings in the array         public static void Main(string[] args) {             var query = from text in strings select text.SafeGetLength(); // no need to do any checks here             Console.WriteLine(query.Sum());         // The output will be: 18          }     } }

在C#语言中,我们通过静态的扩展方法来实现将检查方式统一在方法内部,而不是写的到处都是,上面的例子中是在String类上实现了一个SafeGetLength扩展方法,将为所有String类型提供了一个方法,这样我们在“代码整洁”上又进了一步。

下面我们再来看一个更常用的例子---来自于StackOverFlow

public static class EventExtensions     {         public static void Raise<T>(this EventHandler<T> evnt, object sender, T args)             where T : EventArgs         {             if (evnt != null)             {                 evnt(sender, args);             }         }     }

***,说一个细节问题,以上代码均没有实现“线程安全”,在大牛Eric Lippert的文章中针对线程安全有过一个更精彩的讨论,请戳这里。

改进后的代码时在方法内部增加了一个临时变量,作为方法内部的拷贝,实现线程安全,如果有疑问请参考我的《C#堆vs栈》中对方法内部变量在堆栈上的表现一章。

public class SomeClass     {         public event EventHandler<EventArgs> MyEvent;          private void DoSomething()         {             var tmp = MyEvent;              tmp.Raise(this, EventArgs.Empty);         }     }

 

更“潮”的方式-C#6.0语法

    来自MSDN Magazine的Mark Michaelis(《C#本质论》作者)给我们介绍了C#6.0在语言可能带来的新改进,其中就有针对“Null条件运算符”的改进。

C#6.0更多参考:

Part One: https://msdn.microsoft.com/zh-cn/magazine/dn683793.aspx

Part Two: Https://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx

即使是 .net 开发新手,也可能非常熟悉 NullReferenceException。有一个例外是几乎总是会指出一个 Bug,因为开发人员在调用 (null) 对象的成员之前未进行充分的 null 检查。请看看以下示例:

public static string Truncate(string value, int length) {   string result = value;   if (value != null) // Skip empty string check for elucidation   {     result = value.Substring(0, Math.Min(value.Length, length));   }   return result; }

如果不进行 null 检查,此方法会引发 NullReferenceException。尽管这很简单,但检查字符串参数是否为 null 的过程却稍微有些繁琐。通常,考虑到比较的频率,该繁琐的方法可能没有必要。C# 6.0 包括一个新的 null 条件运算符,可帮助您更加简便地编写这些检查:

public static string Truncate(string value, int length) {             return value?.Substring(0, Math.Min(value.Length, length)); }  [TestMethod] public void Truncate_WithNull_ReturnsNull() {   Assert.AreEqual<string>(null, Truncate(null, 42)); }

根据 Truncate_WithNull_ReturnsNull 方法所演示的内容,如果对象的值实际上为 null,则 null 条件运算符将返回 null。这带来了一个问题,即 null 条件运算符在调用链中出现时会是什么情况?如以下示例中所示:

public static string AdjustWidth(string value, int length) {   return value?.Substring(0, Math.Min(value.Length, length)).PadRight(length); }  [TestMethod] public void AdjustWidth_GivenIniGoMontoya42_ReturnsInigoMontoyaExtended() {   Assert.AreEqual<int>(42, AdjustWidth("Inigo Montoya", 42).Length); }

尽管 Substring 是通过 null 条件运算符进行调用的,并且 null value?.Substring 似乎返回了 null,但语言行为按您的想法进行。这简化了对 PadRight 的调用过程,并立即返回 null,从而避免会导致出现 NullReferenceException 的编程错误。这个概念称为“null 传播”。

Null 条件运算符会根据具体条件进行 null 检查,然后再调用目标方法以及调用链中的所有其他方法。这将可能产生一个令人惊讶的结果,例如,text?.Length.GetType 语句中的结果。

如果 null 条件运算符在调用目标为 null 时返回 null,那么调用会返回值类型的成员时最终会是什么数据类型(假定值类型不能为 null)?例如,从 value?.Length 返回的数据类型不能只是 int。答案当然是:可以为 null 的类型(int?)。实际上,尝试仅将结果分配给 int 将会出现编译错误:

int length = text?.Length; // Compile Error: Cannot implicitly convert type 'int?' to 'int'

Null 条件具有两种语法形式。首先,问号在点运算符前面 (?.)。其次,将问号和索引运算符结合使用。例如,给定一个集合(而非在索引到集合之前显式进行 null 检查),您就可以使用 null 条件运算符执行此操作:

public static IEnumerable<T> GetValueTypeItems<T>(   IList<T> collection, params int[] indexes)   where T : struct {   foreach (int index in indexes)   {     T? item = collection?[index];     if (item != null) yield return (T)item;   } }

此示例使用了运算符 ?[&hellip;] 的 null 条件索引形式,导致仅在集合不为 null 时才索引到集合。通过 null 条件运算符的此形式,T? item = collection?[index] 语句在行为上相当于:

T? item = (collection != null) ? collection[index] : null.

请注意,null 条件运算符仅可检索项目,不会分配项目。如果给定 null 集合,那么这意味着什么?

请注意针对引用类型使用 ?[&hellip;] 时的隐式歧义。由于引用类型可以为 null,因此对于集合是否为 null,或者是否元素本身实际上就是 null 而言,来自 ?[&hellip;] 运算符的 null 结果不明确。

Null 条件运算符的一个非常有用的应用程序解决了 C# 自 C# 1.0 以来一直存在的的一个特性,即在调用委托之前检查是否为 null。我们来看一下中显示的 C# 2.0 代码。

图 1 在调用委托之前检查是否为 Null

class Theremostat {   event EventHandler<float> OnTemperatureChanged;   private int _Temperature;   public int Temperature   {     get     {       return _Temperature;     }     set     {       // If there are any subscribers, then       // notify them of changes in temperature       EventHandler<float> localOnChanged =         OnTemperatureChanged;       if (localOnChanged != null)       {         _Temperature = value;         // Call subscribers         localOnChanged(this, value);       }     }   } }

通过使用 null 条件运算符,整个 set 实现过程就可简化为:

OnTemperatureChanged?.Invoke(this, value)

现在,您只需对将 null 条件运算符作为前缀的 Invoke 进行调用,不再需要将委托实例分配给本地变量,从而实现线程安全,甚至是在调用委托之前显式检查值是否为 null。

C# 开发人员都很想知道在***的四个版本中是否对此内容有所改进。答案是最终进行了改进。仅此一项功能就可以改变调用委托的方式。

另一个 null 条件运算符普及的常见模式是与 coalesce 运算符结合使用。您无需在调用 Length 之前对 linesOfCode 进行 null 检查,而是可以编写项目计数算法,如下所示:

List<string> linesOfCode = ParseSourceCodeFile("Program.cs"); return linesOfCode?.Count ?? 0;

在这种情况下,任何空集合(无项目)和 null 集合均标准化为返回相同数量。总之,null 条件运算符将实现以下功能:

1.  如果操作数为 null,则返回 null

2.  如果操作数为 null,则简化调用链中的其他调用

3.  如果目标成员返回一个值类型,则返回可以为 null 的类型 (System.Nullable<T>)。

4.  以线程安全的方式支持委托调用

5.  可用作成员运算符 (?.) 和索引运算符 (?[&hellip;])

看完上述内容,你们对在NullObject中C#6.0有哪些改进有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: 在NullObject中C#6.0有哪些改进

本文链接: https://www.lsjlt.com/news/287616.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在NullObject中C#6.0有哪些改进
    今天就跟大家聊聊有关在NullObject中C#6.0有哪些改进,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是空引用异常作为一个敲过代码的码农来说,似乎没有谁没有遇到过Null...
    99+
    2023-06-17
  • eXtremeDB 6.0有哪改进
    这篇文章主要介绍“eXtremeDB 6.0有哪改进”,在日常操作中,相信很多人在eXtremeDB 6.0有哪改进问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”eXtrem...
    99+
    2024-04-02
  • 金融版eXtremeDB 6.0功能有哪些改进
    这篇文章主要介绍“金融版eXtremeDB 6.0功能有哪些改进”,在日常操作中,相信很多人在金融版eXtremeDB 6.0功能有哪些改进问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望...
    99+
    2024-04-02
  • PHP8.2有哪些改进
    这篇文章主要介绍了PHP8.2有哪些改进的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP8.2有哪些改进文章都会有所收获,下面我们一起来看看吧。PHP8.2是PHP语言现代化进程中的一个重要的里程碑。除了令...
    99+
    2023-07-04
  • PostgreSQL 12中的改进有哪些
    本篇内容主要讲解“PostgreSQL 12中的改进有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL 12中的改进有哪些”吧!“Auto...
    99+
    2024-04-02
  • Wabacus 3.4有哪些改进
    这篇文章主要介绍了Wabacus 3.4有哪些改进,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。J2EE 快速开发框架 Wabacus 3.4 版已发布,通过该框架,开发者的...
    99+
    2023-06-17
  • Disruptor 2.8有哪些改进
    这篇文章主要介绍Disruptor 2.8有哪些改进,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Disruptor 2.8 发布了,该版本包含如下改进:Create new MultithreadClaimStra...
    99+
    2023-06-17
  • Apache Flink 1.6.0有哪些改进
    小编给大家分享一下Apache Flink 1.6.0有哪些改进,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Apache Flink 1.6.0 重要更新主要包...
    99+
    2023-06-02
  • Fedora13桌面有哪些改进
    本篇内容主要讲解“Fedora13桌面有哪些改进”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Fedora13桌面有哪些改进”吧!以下介绍Fedora 13在桌面使用上的一些新增特性:Packa...
    99+
    2023-06-16
  • Spring Framework 3.0.7有哪些改进
    小编给大家分享一下Spring Framework 3.0.7有哪些改进,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Spring Framework 3.0.7 发布了,可通过 Maven 中心 SpringSource...
    99+
    2023-06-17
  • Ubuntu 14.04 LTS有哪些改进
    这篇文章主要为大家展示了“Ubuntu 14.04 LTS有哪些改进”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ubuntu 14.04 LTS有哪些改进”这篇文章吧。#1:更小的 Unity...
    99+
    2023-06-16
  • Play1.2.4发布有哪些改进
    小编给大家分享一下Play1.2.4发布有哪些改进,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Play1.2.4发布。添加了对java7的支持。更好的数据绑定实...
    99+
    2023-06-17
  • Visual Studio 2010有哪些改进
    这篇文章给大家分享的是有关Visual Studio 2010有哪些改进的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Visual Studio 2010开发代号Rosario(阿根廷港市罗萨里奥),除了上述功能...
    99+
    2023-06-17
  • Samba 3.5.8 发布有哪些改进
    这篇文章主要介绍Samba 3.5.8 发布有哪些改进,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Samba 3.5.8 发布,更新如下:该版本修复了当没有DC生效时,Winbind崩溃问题。域成员查找的bug修复...
    99+
    2023-06-16
  • DynamicReports 2.3.3发布有哪些改进
    小编给大家分享一下DynamicReports 2.3.3发布有哪些改进,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!DynamicReports 2.3.3 发布了,该版本增加对 candlestick 和 highlo...
    99+
    2023-06-17
  • Qomo 1.2发布有哪些改进
    这篇文章给大家分享的是有关Qomo 1.2发布有哪些改进的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。此次发布的Qomo 1.2版本为2月一次的Snapshot版本,在Qomo 1.1的基础上修正了一些Bug,修...
    99+
    2023-06-16
  • Pidgin 2.5.5发布有哪些改进
    这篇文章主要介绍Pidgin 2.5.5发布有哪些改进,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!支持多协议的即时通讯客户端 Pidgin 在几天前发布了新的 2.5.5 版本。Pidgin 2.5.5 改进了 l...
    99+
    2023-06-17
  • KDE v4.2.2发布有哪些改进
    小编给大家分享一下KDE v4.2.2发布有哪些改进,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!KDE是由德国人Mathias Ettrich于1996年开始的...
    99+
    2023-06-17
  • GTK+ 2.16.0发布有哪些改进
    小编给大家分享一下GTK+ 2.16.0发布有哪些改进,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!跨平台图形用户界面开发工具GTK+发布了2.16.0版。新版在...
    99+
    2023-06-17
  • aMule 2.2.4发布有哪些改进
    这篇文章主要介绍了aMule 2.2.4发布有哪些改进,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。P2P 分享软件 aMule 已发布新的 2.2.4 版。aMule 2....
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作