بهبودهای نوعهای ارجاعی نالنپذیر در NET Core 3.0 Preview 7.
پس از نصب SDK جدید، نحوهی فعالسازی این قابلیت در فایل csproj، به صورت زیر درآمدهاست:
این موارد در Preview 7 جدید هستند:
1) امکان اضافه کردن قید جدید notnull در حین تعریف نوعهای جنریک
2) اضافه شدن یک سری ویژگی توکار جدید برای «پیش» بررسی کار با نوعهای ارجاعی نال نپذیر
ویژگی AllowNull به فراخوانها امکان ارسال نال را حتی اگر مجاز نباشد، میدهد. این ویژگی جدید در فضای نام System.Diagnostics.CodeAnalysis تعریف شدهاست. برعکس آن ویژگی DisallowNull، سبب خواهد شد تا فراخوانها حتی در صورت مجاز بودن نیز نتوانند نال ارسال کنند.
در مثال فوق ویژگی AllowNull سبب میشود تا در قسمت setter امکان دریافت نال نیز میسر شود؛ برای مثال جهت سازگاری با نگارشهای قبلی برنامه.
دو ویژگی یاد شده را میتوان بر روی پارامترهای متدها، پارامترهایی از نوع in و ref، فیلدها، خواص و ایندکسرها اعمال کرد.
3) اضافه شدن یک سری ویژگی توکار جدید برای «پس» بررسی کار با نوعهای ارجاعی نال نپذیر
دو ویژگی جدید MaybeNull و NotNull کار پس بررسی نال پذیری را انجام میدهند:
در این مثال، متد Find با تعریف ویژگی return: MaybeNull، ممکن است نال برگرداند. برای مثال اگر چیزی یافت نشد، default را بر گرداند.
در متد Resize، پارامتر array، میتواند نال دریافت کند، چون نالپذیر تعریف شدهاست؛ اما چون به ویژگی NotNull مزین است، حاصل تغییرات بر روی آن (خروجی از متد، از طریق پارامتری از نوع ref) نمیتواند نال باشد.
دو ویژگی یاد شده را میتوان بر روی خروجی متدها، پارامترهایی از نوع out و ref، فیلدها، خواص و ایندکسرها اعمال کرد.
4) اضافه شدن یک سری ویژگی توکار جدید برای «پس» بررسی «شرطی» کار با نوعهای ارجاعی نال نپذیر
در مثالهای زیر کاربردهای دو ویژگی شرطی جدید NotNullWhen و MaybeNullWhen را مشاهده میکنید:
در اینجا با بکارگیری ویژگی [NotNullWhen(false)] به فراخوان اعلام میکنیم که اگر IsNullOrEmpty مقدار false را برگرداند، مقدار value ارسال شدهی به آن، نال نیست.
در اینجا با بکارگیری ویژگی [NotNullWhen(true)] به فراخوان اعلام میکنیم که اگر TryParse مقدار true را برگرداند، مقدار version خروجی آن، نال نیست.
در اینجا با بکارگیری ویژگی [MaybeNullWhen(false)] به فراخوان اعلام میکنیم که اگر TryDequeue مقدار false را برگرداند، مقدار result خروجی آن، میتواند نال هم باشد.
5) اضافه شدن یک سری ویژگی توکار جدید برای شرط گذاشتن بین ورودی و خروجی، در حین کار با نوعهای ارجاعی نال نپذیر
در متد زیر، هم خروجی و هم ورودی آن میتوانند نال باشند. اما میخواهیم اگر path نال نباشد، اطمینان حاصل کنیم که استفاده کننده میداند، خروجی این متد، حتما نال نخواهد بود:
برای انجام یک چنین اطلاع رسانیهایی میتوان از ویژگی جدید NotNullIfNotNull استفاده کرد. از آن میتوان برای مزین سازی خروجی متدها و یا پارامترهایی از نوع ref استفاده کرد.
6) اضافه شدن یک سری ویژگی توکار جدید برای بررسی سیلان برنامه، در حین کار با نوعهای ارجاعی نال نپذیر
در اینجا نحوهی استفاده از دو ویژگی جدید DoesNotReturn و DoesNotReturnIf را مشاهده میکنید:
اگر متد ThrowArgumentNullException در جائی فراخوانی شود، سبب بروز یک استثناء میشود. استفاده از DoesNotReturn سبب میشود تا به کامپایلر اعلام کند، پس از این نقطه، دیگر نیازی به بررسی نال بودن اشیاء نیست؛ چون آن قطعه از کد، غیرقابل اجرا و رسیدن میشود. این ویژگی را تنها بر روی متدها میتوان قرار داد.
اگر متد MyAssert فراخوانی شود و ورودی آن false باشد، یک استثناء را صادر میکند. با بکارگیری ویژگی [DoesNotReturnIf(false)] این موضوع را به کامپایلر اعلام کرده و از آن درخواست میکنیم تا کار بررسی نال بودن اشیاء را از آن سطر به بعد، انجام ندهد. این ویژگی را تنها بر روی پارامترها میتوان اعمال کرد.
پس از نصب SDK جدید، نحوهی فعالسازی این قابلیت در فایل csproj، به صورت زیر درآمدهاست:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <LangVersion>8.0</LangVersion> <Nullable>enable</Nullable> </PropertyGroup> </Project>
این موارد در Preview 7 جدید هستند:
1) امکان اضافه کردن قید جدید notnull در حین تعریف نوعهای جنریک
interface IDoStuff<TIn, TOut> where TIn : notnull where TOut : notnull { TOut DoStuff(TIn input); }
2) اضافه شدن یک سری ویژگی توکار جدید برای «پیش» بررسی کار با نوعهای ارجاعی نال نپذیر
ویژگی AllowNull به فراخوانها امکان ارسال نال را حتی اگر مجاز نباشد، میدهد. این ویژگی جدید در فضای نام System.Diagnostics.CodeAnalysis تعریف شدهاست. برعکس آن ویژگی DisallowNull، سبب خواهد شد تا فراخوانها حتی در صورت مجاز بودن نیز نتوانند نال ارسال کنند.
using System; using System.Diagnostics.CodeAnalysis; namespace ConsoleApp { public class MyClass { private string _innerValue = string.Empty; [AllowNull] public string MyValue { get { return _innerValue; } set { _innerValue = value ?? string.Empty; } } }
دو ویژگی یاد شده را میتوان بر روی پارامترهای متدها، پارامترهایی از نوع in و ref، فیلدها، خواص و ایندکسرها اعمال کرد.
3) اضافه شدن یک سری ویژگی توکار جدید برای «پس» بررسی کار با نوعهای ارجاعی نال نپذیر
دو ویژگی جدید MaybeNull و NotNull کار پس بررسی نال پذیری را انجام میدهند:
public class MyArray { // Result is the default of T if no match is found [return: MaybeNull] public static T Find<T>(T[] array, Func<T, bool> match) { //... } // Never gives back a null when called public static void Resize<T>([NotNull] ref T[]? array, int newSize) { //... } }
در متد Resize، پارامتر array، میتواند نال دریافت کند، چون نالپذیر تعریف شدهاست؛ اما چون به ویژگی NotNull مزین است، حاصل تغییرات بر روی آن (خروجی از متد، از طریق پارامتری از نوع ref) نمیتواند نال باشد.
دو ویژگی یاد شده را میتوان بر روی خروجی متدها، پارامترهایی از نوع out و ref، فیلدها، خواص و ایندکسرها اعمال کرد.
4) اضافه شدن یک سری ویژگی توکار جدید برای «پس» بررسی «شرطی» کار با نوعهای ارجاعی نال نپذیر
در مثالهای زیر کاربردهای دو ویژگی شرطی جدید NotNullWhen و MaybeNullWhen را مشاهده میکنید:
public class MyString { // True when 'value' is null public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) { //... } }
public class MyVersion { // If it parses successfully, the Version will not be null. public static bool TryParse(string? input, [NotNullWhen(true)] out Version? version) { //... } }
public class MyQueue<T> { // 'result' could be null if we couldn't Dequeue it. public bool TryDequeue([MaybeNullWhen(false)] out T result) { //... } }
5) اضافه شدن یک سری ویژگی توکار جدید برای شرط گذاشتن بین ورودی و خروجی، در حین کار با نوعهای ارجاعی نال نپذیر
در متد زیر، هم خروجی و هم ورودی آن میتوانند نال باشند. اما میخواهیم اگر path نال نباشد، اطمینان حاصل کنیم که استفاده کننده میداند، خروجی این متد، حتما نال نخواهد بود:
class MyPath { [return: NotNullIfNotNull("path")] public static string? GetFileName(string? path) { //... } }
6) اضافه شدن یک سری ویژگی توکار جدید برای بررسی سیلان برنامه، در حین کار با نوعهای ارجاعی نال نپذیر
در اینجا نحوهی استفاده از دو ویژگی جدید DoesNotReturn و DoesNotReturnIf را مشاهده میکنید:
internal static class ThrowHelper { [DoesNotReturn] public static void ThrowArgumentNullException(ExceptionArgument arg) { //... } }
public static class MyAssertionLibrary { public static void MyAssert([DoesNotReturnIf(false)] bool condition) { //... } }