غنی سازی کامپایلر C# 9.0 با افزونه‌ها
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: یازده دقیقه

از زمانیکه کامپایلر #C، تحت عنوان Roslyn بازنویسی شد، قابلیت افزونه‌پذیری نیز پیدا کرد. برای مثال می‌توان آنالیز کننده‌ای را طراحی کرد که در پروسه‌ی کامپایل متداول کدهای  #C مورد استفاده قرار گرفته و خطاها و یا اخطارهایی را صادر کند که جزئی از پیام‌های استاندارد کامپایلر #C نیستند. در این مطلب نحوه‌ی معرفی آن‌ها را به پروژه‌های جدید NET 5.0.، بررسی می‌کنیم.


معرفی تعدادی آنالیز کننده‌ی کد که به عنوان افزونه‌ی کامپایلر #C قابل استفاده هستند

Microsoft.CodeAnalysis.NetAnalyzers
این افزونه جزئی از SDK دات نت 5 است و نیازی به نصب مجزا را ندارد. البته اگر می‌خواهید نگارش‌های جدیدتر آن‌را پیش از یکی شدن با SDKهای بعدی مورد آزمایش قرار دهید، می‌توان آن‌را به صورت صریحی نیز به کامپایلر معرفی کرد. این افزونه‌ی جایگزین FxCop است و پس از ارائه‌ی آن، FxCop را منسوخ شده اعلام کردند.

Meziantou.Analyzer
یکسری نکات بهبود کیفیت کدها که توسط Meziantou در طی سال‌های متمادی جمع آوری شده‌اند، تبدیل به افزونه‌ی فوق شده‌اند.

Microsoft.VisualStudio.Threading.Analyzers
این افزونه نکاتی را در مورد مشکلات Threading موجود در کدها، گوشزد می‌کند.

Microsoft.CodeAnalysis.BannedApiAnalyzers
با استفاده از این افزونه می‌توان استفاده‌ی از یکسری کدها را ممنوع کرد. برای مثال استفاده‌ی از System.DateTimeOffset.DateTime، در سراسر کدها ممنوع شده و استفاده‌ی از System.DateTimeOffset.UtcDateTime پیشنهاد شود.

AsyncFixer و Asyncify
این دو افزونه، مشکلات متداول در حین کار با کدهای async را گوشزد می‌کنند.

ClrHeapAllocationAnalyzer
این افزونه مکان‌هایی از کد را مشخص می‌کنند که در آن‌ها تخصیص حافظه صورت گرفته‌است. کاهش این مکان‌ها می‌تواند به بالا رفتن کارآیی برنامه کمک کنند.

SonarAnalyzer.CSharp
مجموعه‌ی معروف Sonar، که تعداد قابل ملاحظه‌ای بررسی کننده‌ی کد را به پروژه‌ی شما اضافه می‌کنند.


روش معرفی سراسری افزونه‌های فوق به تمام پروژه‌های یک Solution

می‌توان تنظیمات زیر را به یک تک پروژه اعمال کرد که برای اینکار نیاز است فایل csproj آن‌را ویرایش نمود و یا می‌توان یک تک فایل ویژه را به نام Directory.Build.props ایجاد کرد و آن‌را به صورت زیر تکمیل نمود. محل قرارگیری این فایل، در ریشه‌ی Solution و در کنار فایل sln می‌باشد.
<Project>
  <PropertyGroup>
    <AnalysisLevel>latest</AnalysisLevel>
    <AnalysisMode>AllEnabledByDefault</AnalysisMode>
    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
    <EnableNETAnalyzers>true</EnableNETAnalyzers>
    <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
    <Nullable>enable</Nullable>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
    <RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
    <!--
      CA2007: Consider calling ConfigureAwait on the awaited task
      MA0004: Use Task.ConfigureAwait(false) as the current SynchronizationContext is not needed
      CA1056: Change the type of property 'Url' from 'string' to 'System.Uri'
      CA1054: Change the type of parameter of the method to allow a Uri to be passed as a 'System.Uri' object
      CA1055: Change the return type of method from 'string' to 'System.Uri'
    -->
    <NoWarn>$(NoWarn);CA2007;CA1056;CA1054;CA1055;MA0004</NoWarn>
    <NoError>$(NoError);CA2007;CA1056;CA1054;CA1055;MA0004</NoError>
    <Deterministic>true</Deterministic>
    <Features>strict</Features>
    <ReportAnalyzer>true</ReportAnalyzer>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Meziantou.Analyzer" Version="1.0.639">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="16.8.55">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="AsyncFixer" Version="1.3.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Asyncify" Version="0.9.7">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="ClrHeapAllocationAnalyzer" Version="3.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="SonarAnalyzer.CSharp" Version="8.16.0.25740">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <AdditionalFiles Include="$(MSBuildThisFileDirectory)BannedSymbols.txt" Link="Properties/BannedSymbols.txt" />
  </ItemGroup>
</Project>
توضیحات:
- در تنظیمات فوق، مواردی مانند AnalysisLevel، در مطلب «کامپایلر C# 9.0، خطاها و اخطارهای بیشتری را نمایش می‌دهد» پیشتر بررسی شده‌اند.
- در اینجا Nullable به true تنظیم شده‌است. اگر قرار است یک پروژه‌ی جدید را شروع کنید، بهتر است این ویژگی را نیز فعال کنید. بسیاری از API‌های دات نت 5 جهت مشخص سازی خروجی نال و یا غیرنال آن‌ها، بازنویسی و تکمیل شده‌اند و بدون استفاده از این ویژگی، بسیاری از راهنمایی‌های ارزنده‌ی دات نت 5 را از دست خواهید داد. اساسا بدون فعالسازی این ویژگی، از قابلیت‌های #C مدرن استفاده نمی‌کنید.
- وجود این PackageReference ها، به معنای بالا رفتن حجم نهایی قابل ارائه‌ی پروژه نیست؛ چون به صورت PrivateAssets و analyzers تعریف شده‌اند و فقط در حین پروسه‌ی کامپایل، جهت ارائه‌ی راهنمایی‌های بیشتر، تاثیرگذار خواهند بود.
- این تنظیمات طوری چیده شده‌اند که تا حد ممکن «درد آور» باشند! برای اینکار CodeAnalysisTreatWarningsAsErrors و TreatWarningsAsErrors به true تظیم شده‌اند تا حتی اخطارها نیز به صورت خطای کامپایلر گزارش شوند؛ تا مجبور به رفع آن‌ها شویم.
- در اینجا فایل BannedSymbols.txt را نیز مشاهده می‌کنید که مرتبط است به BannedApiAnalyzers. می‌توان در کنار فایل Directory.Build.props، فایل جدید BannedSymbols.txt را با این محتوا ایجاد کرد:
# https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md
P:System.DateTime.Now;Use System.DateTime.UtcNow instead
P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead
P:System.DateTimeOffset.DateTime;Use System.DateTimeOffset.UtcDateTime instead
در این حالت برای مثال، از استفاده‌ی از DateTime.Now منع شده و وادار به استفاده‌ی از DateTime.UtcNow می‌شوید.


روش کاهش تعداد خطاهای نمایش داده شده

اگر از فایل Directory.Build.props فوق استفاده کرده و یکبار دستور dotnet restore را جهت بازیابی وابستگی‌های آن اجرا کنید، با تعداد خطاهایی که در IDE خود مشاهده خواهید کرد، شگفت‌زده خواهید شد! به همین جهت برای کنترل آن‌ها می‌توان فایل جدید editorconfig. را به نحو زیر در کنار فایل Directory.Build.props ایجاد و تکمیل کرد:
[*.cs]

# MA0026 : Complete the task
dotnet_diagnostic.MA0026.severity = suggestion

# CA1308: In method 'urlToLower', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (CA1308)
dotnet_diagnostic.CA1308.severity = suggestion

# CA1040: Avoid empty interfaces
dotnet_diagnostic.CA1040.severity = suggestion

# CA1829 Use the "Count" property instead of Enumerable.Count()
dotnet_diagnostic.CA1829.severity = suggestion

# Use 'Count' property here instead.
dotnet_diagnostic.S2971.severity = suggestion

# S1135 : Complete the task
dotnet_diagnostic.S1135.severity = suggestion

# S2479: Replace the control character at position 7 by its escape sequence
dotnet_diagnostic.S2479.severity = suggestion

# CA2007: Consider calling ConfigureAwait on the awaited task
dotnet_diagnostic.CA2007.severity = none

# MA0004: Use Task.ConfigureAwait(false) as the current SynchronizationContext is not needed
dotnet_diagnostic.MA0004.severity = none

# CA1056: Change the type of property 'Url' from 'string' to 'System.Uri'
dotnet_diagnostic.CA1056.severity = suggestion

# CA1054: Change the type of parameter of the method to allow a Uri to be passed as a 'System.Uri' object
dotnet_diagnostic.CA1054.severity = suggestion

# CA1055: Change the return type of method from 'string' to 'System.Uri'
dotnet_diagnostic.CA1055.severity = suggestion

# S4457: Split this method into two, one handling parameters check and the other handling the asynchronous code.
dotnet_diagnostic.S4457.severity = none

# AsyncFixer01: Unnecessary async/await usage
dotnet_diagnostic.AsyncFixer01.severity = suggestion

# AsyncFixer02: Long-running or blocking operations inside an async method
dotnet_diagnostic.AsyncFixer02.severity = error

# VSTHRD103: Call async methods when in an async method
dotnet_diagnostic.VSTHRD103.severity = error

# AsyncFixer03: Fire & forget async void methods
dotnet_diagnostic.AsyncFixer03.severity = error

# VSTHRD100: Avoid async void methods
dotnet_diagnostic.VSTHRD100.severity = error

# VSTHRD101: Avoid unsupported async delegates
dotnet_diagnostic.VSTHRD101.severity = error

# VSTHRD107: Await Task within using expression
dotnet_diagnostic.VSTHRD107.severity = error

# AsyncFixer04: Fire & forget async call inside a using block
dotnet_diagnostic.AsyncFixer04.severity = error

# VSTHRD110: Observe result of async calls
dotnet_diagnostic.VSTHRD110.severity = error

# VSTHRD002: Avoid problematic synchronous waits
dotnet_diagnostic.VSTHRD002.severity = suggestion

# MA0045: Do not use blocking call (make method async)
dotnet_diagnostic.MA0045.severity = suggestion

# AsyncifyInvocation: Use Task Async
dotnet_diagnostic.AsyncifyInvocation.severity = error

# AsyncifyVariable: Use Task Async
dotnet_diagnostic.AsyncifyVariable.severity = error

# VSTHRD111: Use ConfigureAwait(bool)
dotnet_diagnostic.VSTHRD111.severity = none

# MA0022: Return Task.FromResult instead of returning null
dotnet_diagnostic.MA0022.severity = error

# VSTHRD114: Avoid returning a null Task
dotnet_diagnostic.VSTHRD114.severity = error

# VSTHRD200: Use "Async" suffix for async methods
dotnet_diagnostic.VSTHRD200.severity = suggestion

# MA0040: Specify a cancellation token
dotnet_diagnostic.MA0032.severity = suggestion

# MA0040: Flow the cancellation token when available
dotnet_diagnostic.MA0040.severity = suggestion

# MA0079: Use a cancellation token using .WithCancellation()
dotnet_diagnostic.MA0079.severity = suggestion

# MA0080: Use a cancellation token using .WithCancellation()
dotnet_diagnostic.MA0080.severity = error

#AsyncFixer05: Downcasting from a nested task to an outer task.
dotnet_diagnostic.AsyncFixer05.severity = error

# ClrHeapAllocationAnalyzer ----------------------------------------------------
# HAA0301: Closure Allocation Source
dotnet_diagnostic.HAA0301.severity = suggestion

# HAA0601: Value type to reference type conversion causing boxing allocation
dotnet_diagnostic.HAA0601.severity = suggestion

# HAA0302: Display class allocation to capture closure
dotnet_diagnostic.HAA0302.severity = suggestion

# HAA0101: Array allocation for params parameter
dotnet_diagnostic.HAA0101.severity = suggestion

# HAA0603: Delegate allocation from a method group
dotnet_diagnostic.HAA0603.severity = suggestion

# HAA0602: Delegate on struct instance caused a boxing allocation
dotnet_diagnostic.HAA0602.severity = suggestion

# HAA0401: Possible allocation of reference type enumerator
dotnet_diagnostic.HAA0401.severity = silent

# HAA0303: Lambda or anonymous method in a generic method allocates a delegate instance
dotnet_diagnostic.HAA0303.severity = silent

# HAA0102: Non-overridden virtual method call on value type
dotnet_diagnostic.HAA0102.severity = silent

# HAA0502: Explicit new reference type allocation
dotnet_diagnostic.HAA0502.severity = none

# HAA0505: Initializer reference type allocation
dotnet_diagnostic.HAA0505.severity = silent
روش کار هم به صورت است که برای مثال در IDE خود (حتی با VSCode هم کار می‌کند)، خطای کامپایلر مثلا CA1308 را مشاهده می‌کنید که عنوان کرده‌است بجای ToLowerInvariant از ToUpperInvariant استفاده کنید. اگر با این پیشنهاد موافق نیستید (عین خطا را به صورت C# CA1308 در گوگل جستجو کنید؛ توضیحات مایکروسافت را در مورد آن خواهید یافت)، یک سطر شروع شده‌ی با dotnet_diagnostic و سپس ID خطا را به صورت زیر، به فایل editorconfig. یاد شده، اضافه کنید:
dotnet_diagnostic.CA1308.severity = suggestion
به این ترتیب هنوز هم این مورد را به صورت یک پیشنهاد مشاهده خواهید کرد، اما دیگر جزو خطاهای کامپایلر گزارش نمی‌شود. اگر خواستید که به طور کامل ندید گرفته شود، مقدار آن‌را بجای suggestion به none تغییر دهید.

یک نکته: در ویندوز نمی‌توانید یک فایل تنها پسوند دار را به صورت معمولی در windows explorer ایجاد کنید. نام این فایل را به صورت .editorconfig. با دو نقطه‌ی ابتدایی و انتهایی وارد کنید. خود ویندوز نقطه‌ی پایانی را حذف می‌کند.


روش صرفنظر کردن از یک خطا، تنها در یک قسمت از کد

فرض کنید نمی‌خواهید خطای CA1052 را تبدیل به یک suggestion سراسری کنید و فقط می‌خواهید که در قطعه‌ی خاصی از کدهای خود، آن‌را خاموش کنید. به همین جهت بجای اضافه کردن آن به فایل editorconfig.، باید از ویژگی SuppressMessage به صورت زیر استفاده نمائید:
[SuppressMessage("Microsoft.Usage", "CA1052:Type 'Program' is a static holder type but is neither static nor NotInheritable",
  Justification = "We need it for our integration tests this way.")]
[SuppressMessage("Microsoft.Usage", "RCS1102:Type 'Program' is a static holder type but is neither static nor NotInheritable",
  Justification = "We need it for our integration tests this way.")]
[SuppressMessage("Microsoft.Usage", "S1118:Type 'Program' is a static holder type but is neither static nor NotInheritable",
  Justification = "We need it for our integration tests this way.")]
public class Program { }
در اینجا پارامتر اول با Microsoft.Usage مقدار دهی می‌شود. پارامتر دوم آن باید حاوی ID خطا باشد. در صورت تمایل می‌توانید دلیل خاموش کردن این خطا را در قسمت Justification وارد کنید.
  • #
    ‫۳ سال و ۸ ماه قبل، دوشنبه ۸ دی ۱۳۹۹، ساعت ۰۲:۴۷
    در آخرین نسخه Resharper تقریبا" چند درصد از این آنالیزکننده‌ها پوشش داده شده اند؟
  • #
    ‫۳ سال و ۸ ماه قبل، چهارشنبه ۱۷ دی ۱۳۹۹، ساعت ۱۱:۵۸
    یک نکته‌ی تکمیلی
    با انتشار «NetAnalyzers 5.0.3» روش استفاده‌ی از آن، ذکر صریح PackageReference ای است که در متن عنوان شد؛ در غیراینصورت (استفاده از نگارش قدیمی به همراه SDK)، نیازی به این تنظیم را ندارد.
  • #
    ‫۳ سال و ۸ ماه قبل، چهارشنبه ۱۷ دی ۱۳۹۹، ساعت ۱۲:۰۴
    یک نکته‌ی تکمیلی
    security-code-scan را هم می‌توان به عنوان یک افزونه‌ی بررسی مسایل امنیتی، به مجموعه‌ی تنظیمات فوق اضافه کرد:
    <PackageReference Include="SecurityCodeScan" Version="3.5.3">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  • #
    ‫۳ سال و ۸ ماه قبل، یکشنبه ۲۱ دی ۱۳۹۹، ساعت ۱۷:۰۲

    فرض کنید نمی‌خواهید فایل‌های migration حاصل از ابزارهای EF-Core را وارد پروسه‌ی آنالیز افزونه‌ها کنید؛ چون این فایل‌ها به صورت خودکار تولید می‌شوند و اصلاح آن‌ها، یا کیفیت آن‌ها، مشکل ما نیست. برای این منظور، فقط کافی است داخل پوشه‌ی migrations، یک فایل اختصاصی editorconfig. را با محتوای زیر قرار داد:
    [*.cs]
    generated_code = true
    به این ترتیب تمام فایل‌های cs قرارگرفته‌ی در این پوشه، به عنوان «کدهای به صورت خودکار تولید شده» علامتگذاری شده و دیگر مشکلات کیفیتی آن‌ها وارد پروسه‌ی آنالیز و build برنامه نمی‌شوند.
  • #
    ‫۲ سال و ۵ ماه قبل، شنبه ۲۰ فروردین ۱۴۰۱، ساعت ۱۴:۳۳
    یک نکته‌ی تکمیلی: چگونه اخطارهای code styleها را هم در پروسه‌ی Build وارد کنیم؟

    Roslyn analyzers به همراه پیشنهادهایی در مورد code styles هم هستند؛ برای مثال توصیه‌ی به استفاده‌ی از var و یا عکس آن. می‌توان این توصیه‌ها را تبدیل به اجبار هم کرد تا در یک تیم، code styles یکدستی ارائه شود و روش آن، وارد کردن این توصیه‌ها به پروسه‌ی build است. برای اینکار می‌توان فایل csproj را به نحو زیر ویرایش کرد:
    <PropertyGroup>
       <TargetFramework>net6.0</TargetFramework>
    
       <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
    </PropertyGroup>
    اکنون با فعالسازی EnforceCodeStyleInBuild، یک مرحله‌ی دیگر نیز باقی است. باید به فایل editorconfig. مراجعه و تنظیم زیر را به آن افزود:
    [*.cs]
    # Default severity for analyzer diagnostics with category 'Style' (escalated to build warnings)
    dotnet_analyzer_diagnostic.category-Style.severity = warning
    پس از این تنظیمات، توصیه‌های مرتبط با code-styles، به صورت اخطارهای کامپایلر ظاهر می‌شوند و یا حتی اگر علاقمند بودید، می‌توان مقدار warning فوق را به error نیز تغییر داد تا دیگر در صورت وجود توصیه‌ی خاصی، برنامه کامپایل نشود.

    بدیهی است در این صورت، روش لغو توصیه‌ی خاصی به صورت زیر است:
     dotnet_diagnostic.IDE0008.severity = none
    IDE0008 برای نمونه شماره‌ی یکی از توصیه‌هایی است که با آن موافق نیستید. در این حالت فقط کافی است severity آن‌را به none تنظیم کنید تا دیگر در پروسه‌ی build ظاهر نشود.
  • #
    ‫۲ سال و ۵ ماه قبل، شنبه ۲۰ فروردین ۱۴۰۱، ساعت ۱۴:۴۱
    یک نکته‌ی تکمیلی: چگونه یک پروژه یا پوشه‌ی خاصی را از ارث‌بری editorconfig. خارج کنیم؟

    زمانیکه فایل editorconfig. در ریشه‌ی solution قرار می‌گیرد، تنظیمات آن به کل زیر پوشه‌های موجود نیز اعمال می‌شود. اگر می‌خواهید پوشه یا پروژه‌ی خاصی از حالت ارث‌بری این تنظیمات خارج شود، می‌توان یک سطر زیر را به editorconfig. جدید و خاص آن پوشه اضافه کرد:
    # Remove the line below if you want to inherit .editorconfig settings from higher directories
    root = true
  • #
    ‫۱ سال و ۹ ماه قبل، جمعه ۲۷ آبان ۱۴۰۱، ساعت ۲۲:۴۳
    یک نکته‌ی تکمیلی: تاثیر آنالایزرها بر روی سرعت build
    هر چقدر تعداد آنالایزر بیشتری را مورد استفاده قرار دهید، به همان نسبت سرعت build هم کمتر می‌شود. به همین جهت می‌توان آن‌ها را بر اساس حالات build، فعال و یا غیرفعال کرد. برای مثال فعال سازی آنالایزرها تنها در حالت debug:
    <ItemGroup Condition="'$(Configuration)' == 'Debug'">
    </ItemGroup>
  • #
    ‫۱ سال و ۷ ماه قبل، جمعه ۲۱ بهمن ۱۴۰۱، ساعت ۱۳:۳۱
    یک نکته‌ی تکمیلی: ارتقاء به NET 7.0.12. و دریافت خطای CA1852

    اگر نکات این مطلب را پیاده سازی کرده و برای مثال TreatWarningsAsErrors را فعال کرده باشید، با ارتقاء به NET 7.0.102. حتی در مورد فایل Program.cs نیز خطای زیر را دریافت خواهید کرد:
    CA1852:  Type can be sealed because it has no subtypes in its containing assembly and is not externally visible
    عموما از هر نگارشی به نگارش دیگر، تعداد آنالایزرهای توکار دات نت بیشتر می‌شوند. یک چنین موردی در نگارش ابتدایی دات نت 7 وجود نداشت، اما الان قابل مشاهده است. در جهت مواجه شدن با آن یا می‌توان کلاس عنوان شده را با واژه‌ی کلیدی sealed مزین کرد و یا فقط کافی است فایل editorconfig. را باز کرده و یک سطر زیر را به آن اضافه کنید:
    dotnet_diagnostic.CA1852.severity = suggestion
    به این صورت میزان شدت گزارش یاد شده، صرفا به یک توصیه تقلیل پیدا می‌کند و مانع build برنامه نخواهد شد؛ هرچند در IDE هنوز به صورت یک هشدار آبی رنگ قابل مشاهده‌است.
  • #
    ‫۱ سال و ۴ ماه قبل، دوشنبه ۱۱ اردیبهشت ۱۴۰۲، ساعت ۱۸:۴۷
    یک نکته‌ی تکمیلی: تنظیم severity = suggestion در فایل editorconfig. اعمال نمی‌شود!
    - اگر تنظیمات آنالیزری را در حالت «توصیه» تنظیم کردید، اما باز هم در حین Build مشاهده کردید که اعمال نمی‌شود و تنظیم دیگری برای آن اعمال شده، ممکن است به علت وجود پروسه‌های dotnet.exe در حال اجرای پیشین باشد. تمام آن‌ها را از طریق task manager خاتمه دهید و مجددا سعی کنید.
    - و یا اگر از فایل Directory.Build.props استفاده می‌کنید، ممکن است در قسمت‌های NoError و NoWarn، یکسری از تنظیمات را بازنویسی کرده باشید (مانند مثال مطرح شده‌ی در مطلب جاری).
  • #
    ‫۱ سال و ۳ ماه قبل، جمعه ۱۲ خرداد ۱۴۰۲، ساعت ۱۸:۵۰
    پروژه‌ی «Meziantou.DotNet.CodingStandard» کار تولید خودکار لیست بررسی کننده‌های یک آنالیزر و تبدیل آن‌ها به فایل‌های editorconfig. را انجام می‌دهد که در آن‌ها  این بررسی کننده‌ها به حالت warning تنظیم شده‌اند. علت اینجا است که ممکن است خود آنالیزر، این‌ها را به صورت پیش‌فرض در حالت توصیه، تنظیم کرده باشد. هدف، سخت‌گیری بیشتر است.
  • #
    ‫۱ سال و ۲ ماه قبل، چهارشنبه ۲۱ تیر ۱۴۰۲، ساعت ۱۳:۴۱
    پروژه‌ی «StyleCopAnalyzers» که از سال 2019، ارائه‌ی پایداری نداشته، مجددا در حال پیگیری است و فعلا نگارش بتای جدید آن در دسترس است.
  • #
    ‫۱۱ ماه قبل، جمعه ۲۸ مهر ۱۴۰۲، ساعت ۲۰:۴۲
    CodeQL هم در این بین جایگاه فوق‌العاده‌ای دارد و خروجی آن قابل رقابت با محصول تجاری مانند PVS-Studio است.
  • #
    ‫۱ ماه قبل، پنجشنبه ۱ شهریور ۱۴۰۳، ساعت ۰۸:۰۴

    یک نکته‌ی تکمیلی: جهت بررسی رعایت یکسری از اصول مقدماتی کار با MSTest، می‌توان از آنالایزر جدیدی به نام MSTest.Analyzers استفاده کرد. اطلاعات بیشتر