Improving non-nullable reference types handling

栏目: IT技术 · 发布时间: 4年前

内容简介:A few weeks ago I started usingThe main thing that started getting on my nerves was diagnostic
Improving non-nullable reference types handling

A few weeks ago I started using non-nullable reference types - a new C# language feature which was shipped with version 8.0. It wasn’t a completely new experience for me, because I was working before on projects that were heavily utilizing [NotNull] and [CanBeNull] Resharper annotations . The way how non-nullable types are handled by Roslyn seems to be a little more complex in comparison to Resharper - there are around 40 different diagnostics related to this area. This large amount of inspections is good because it very often brings your attention to the edge cases that you would probably overlook, but on the other hand, it sometimes makes the development more tedious. The project on which I’m working is a greenfield, so I enabled the not-nullable feature on the whole solution scope and set the severity level for all of those rules to error . After a couple of days working with such setup, I got the feeling that I needed to put in much more effort than I was getting out of it.

Problems with non-nullable reference types

The main thing that started getting on my nerves was diagnostic CS8618: Non-nullable field is uninitialized. Consider declaring as nullable. This rule enforces on us mandatory field initialization to guarantee non-nullable value, which can be satisfied by providing the value directly in the field definition or through the containing type’s constructor. In most cases, when there are no constraints to guard beside the nullability check, adding such constructor introduces unnecessary complexity to our codebase, especially for large POCO types.

Improving non-nullable reference types handling

The situation is especially confusing for generic types because CS8618 is reported for generic fields too, even when there is no constraint that suggests the generic type parameter is a reference type.

Improving non-nullable reference types handling

There is a way to dismiss this diagnostic by initializing the field with null! for reference types and default! for generics:

Improving non-nullable reference types handling

But this is rather a dirty hack that hides the real problem instead of solving it. If we want to go that way, then we might as well completely disable CS8618 , for example with the following entry in .editorconfig :

[*.cs]

# CS8618: Non-nullable field is uninitialized. Consider declaring as nullable.
dotnet_diagnostic.CS8618.severity = none

Proposition of improvements

Recently, I’ve been experimenting with Roslyn analyzer that could enforce mandatory initialization via initialization block for members decorated with special attributes. I’ve come up with two attributes [InitRequired] and [InitOnly] - you can read about them in my previous blog post Immutable types in C# with Roslyn . Those attributes basically move the responsibility for field initialization from class creator to class users. Everyone who wants to create a new class instance, is obligated to provide values for all non-nullable reference fields via initialization block. However, using those attributes solves the problem only partially because the compiler still keeps reporting CS8618 diagnostic. To solve that issue, I implemented a dedicated DiagnosticSuppressor which discards CS8618 for fields and properties marked with those properties.

Improving non-nullable reference types handling

If we want to use that approach through the entire codebase, adding an additional attribute to every non-nullable reference field could result in unnecessary noise. It seemed to be an imperfect solution, so I decided to take it on the next level and I introduced [InitRequiredForNotNull] attribute. Applying this attribute on the assembly level results with required initialization via init block for all non-nullable reference fields and properties and automatic discard of CS8618 for all those members.

Improving non-nullable reference types handling

This solution works pretty well also with generics because it enforces mandatory initialization only when the generic parameter is bound to non-nullable reference type:

Improving non-nullable reference types handling

Important:If you like the idea of [InitRequiredForNotNull] attribute and you are going to use it in your project, please make sure that all your teammates know about it.

All attributes and analyzers described here are available as a single Nuget package SmartAnalyzers.CSharpExtensions.Annotations . The source code is published on Github under CSharpExtensions project. Please let me know what you think about those extensions to C# language and if you encounter any problems with using it, feel free to report an issue on Github page.

If you find this blog post useful and you think it's worth to share this idea with others, please don't hesitate to use these buttons below:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web前端黑客技术揭秘

Web前端黑客技术揭秘

钟晨鸣、徐少培 / 电子工业出版社 / 2013-1 / 59.00元

Web前端的黑客攻防技术是一门非常新颖且有趣的黑客技术,主要包含Web前端安全的跨站脚本(XSS)、跨站请求伪造(CSRF)、界面操作劫持这三大类,涉及的知识点涵盖信任与信任关系、Cookie安全、Flash安全、DOM渲染、字符集、跨域、原生态攻击、高级钓鱼、蠕虫思想等,这些都是研究前端安全的人必备的知识点。本书作者深入剖析了许多经典的攻防技巧,并给出了许多独到的安全见解。 本书适合前端工......一起来看看 《Web前端黑客技术揭秘》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具