گاهی از اوقات ممکن است یک ویژگی تکمیل نشده، سر از نگارشهای release درآورد؛ چون نیاز به دریافت بازخوردی در این مورد وجود دارد و یا اینکه قرار است در طی چند مرحله تکمیل شود. برای اینکه یک چنین مسالهای خصوصا از طرف نویسندگان کتابخانهها و فریمورکها مشخص شود، ویژگی جدید System.Diagnostics.CodeAnalysis.ExperimentalAttribute به داتنت 8 اضافه شدهاست.
در این حالت اگر کدی، شروع به استفادهی از یک چنین عضوهای آزمایشی کند، یک خطای زمان کامپایل رخ میدهد؛ مگر اینکه آن قطعه کد نیز دقیقا با همین ویژگی مزین شود. در اینجا میتوان نوعها، اسمبلیها و حتی اعضای آنها را آزمایشی تعریف کرد. اگر کل یک نوع را به صورت آزمایشی معرفی کنیم، تمام اعضای آن هم آزمایشی خواهند بود.
بررسی ویژگی Experimental با یک مثال
در ادامه نحوهی اعمال ویژگی Experimental را به همراه یک diagnosticId که به کل یک کلاس اعمال شدهاست، مشاهده میکنید. از این diagnosticId در حین تولید متن خطاها و یا برای شناسایی آنها، استفاده میشود:
پس از این تعریف، اگر در قسمت دیگری از برنامه بخواهیم از این کلاس استفاده کنیم:
با خطای زیر مواجه خواهیم شد:
برای مواجه شدن با یک چنین خطایی، میتوان دو روش زیر را در پیش گرفت:
الف) غیرفعال کردن سراسری گزارش این نوع خطاها در فایل csproj. برنامه:
در اینجا اضافه شدن NoWarn را بر اساس diagnosticId ویژگی آزمایشی تعریف شده، مشاهده میکنید. این تنظیم سراسری است و به تمام قسمتهای پروژهی جاری اعمال میشود. اضافه کردن آن هم فقط یکبار صورت میگیرد.
ب) غیرفعال کردن موضعی آن، صرفا در محل استفاده
برای غیرفعال کردن محلی این بررسی، تنها کافی است با استفاده از pragma warning# یکبار آنرا غیرفعال کرده و پس از پایان کار، مجددا آنرا فعال کنیم:
همانطور که مشاهده میکنید، این فعال و غیرفعال کردن هم بر اساس diagnosticId صورت میگیرد. بدیهی است این تنظیم سراسری نبوده و درصورت بکارگیری این قطعه کد در قسمتهای دیگر برنامه، باید مجددا تکرار شود.
و اگر این مثال را کمی پیچیدهتر کنیم، به حالت زیر میرسیم:
در اینجا دو ویژگی آزمایشی، با دو diagnosticId متفاوت تعریف شدهاند. در این حالت اگر سعی کنیم قطعه کد زیر را کامپایل کنیم:
به ازای هر ویژگی آزمایشی تعریف شده، یک خطای کامپایلر جداگانه را دریافت میکنیم. به همین جهت برای رفع این خطاها، یا باید از روش غیرفعال سازی سراسری آنها پیشرفت:
و یا میتوان به صورت محلی زیر عمل کرد:
در اینجا ذکر هر دو diagnosticId، ضروری است.
در این حالت اگر کدی، شروع به استفادهی از یک چنین عضوهای آزمایشی کند، یک خطای زمان کامپایل رخ میدهد؛ مگر اینکه آن قطعه کد نیز دقیقا با همین ویژگی مزین شود. در اینجا میتوان نوعها، اسمبلیها و حتی اعضای آنها را آزمایشی تعریف کرد. اگر کل یک نوع را به صورت آزمایشی معرفی کنیم، تمام اعضای آن هم آزمایشی خواهند بود.
بررسی ویژگی Experimental با یک مثال
در ادامه نحوهی اعمال ویژگی Experimental را به همراه یک diagnosticId که به کل یک کلاس اعمال شدهاست، مشاهده میکنید. از این diagnosticId در حین تولید متن خطاها و یا برای شناسایی آنها، استفاده میشود:
using System.Diagnostics.CodeAnalysis; namespace CS8Tests; [Experimental(diagnosticId: "Test001")] public class ExperimentalAttributeDemo { public void Print() { Console.WriteLine("Hello Experimental Attribute"); } }
var experimentalAttributeDemo = new ExperimentalAttributeDemo();
error Test001: 'CS8Tests.ExperimentalAttributeDemo' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
الف) غیرفعال کردن سراسری گزارش این نوع خطاها در فایل csproj. برنامه:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <NoWarn>Test001</NoWarn> </PropertyGroup> </Project>
ب) غیرفعال کردن موضعی آن، صرفا در محل استفاده
برای غیرفعال کردن محلی این بررسی، تنها کافی است با استفاده از pragma warning# یکبار آنرا غیرفعال کرده و پس از پایان کار، مجددا آنرا فعال کنیم:
#pragma warning disable Test001 var demo = new ExperimentalAttributeDemo(); #pragma warning restore Test001
و اگر این مثال را کمی پیچیدهتر کنیم، به حالت زیر میرسیم:
using System.Diagnostics.CodeAnalysis; namespace CS8Tests; [Experimental(diagnosticId: "Test001")] public class ExperimentalAttributeDemo { [Experimental(diagnosticId: "Test002")] public void Print() { Console.WriteLine("Hello Experimental Attribute"); } }
var demo = new ExperimentalAttributeDemo(); demo.Print();
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <NoWarn>Test001,Test002</NoWarn> </PropertyGroup> </Project>
#pragma warning disable Test001,Test002 var demo = new ExperimentalAttributeDemo(); demo.Print(); #pragma warning restore Test001,Test002