معرفی تعدادی آنالیز کنندهی کد که به عنوان افزونهی کامپایلر #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
روش کاهش تعداد خطاهای نمایش داده شده
اگر از فایل 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
dotnet_diagnostic.CA1308.severity = suggestion
یک نکته: در ویندوز نمیتوانید یک فایل تنها پسوند دار را به صورت معمولی در 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 { }
At the Build 2016 conference, Microsoft announced the Microsoft Bot Framework, a package of tools for building intelligent bots that could be integrated with a variety of communication platforms. With Microsoft Bot Framework Succinctly, you can jump right into building your own bots with the framework, whether you want to make bots for personal use only, or customer-facing bots for your business. Author Ed Freitas provides clear guidance from setting up a bot project in Visual Studio and writing your first bare-bones bot, to publishing one capable of searching for current flight prices.
- Introduction
- Bot Framework Overview
- Our First Bot
- Publishing Our Bot
- The QPX Express API
- Airfare Alert Bot
معرفی سایت fuget.org
چرا Babel خوبه ؟
ایجاد یک Reverse Proxy در NET Core.
This article will show you how to implement a reverse proxy in C# and .NET Core to overcome specific needs that you could hardly solve with an out-of-the-box software. You can find the code of the final project on this GitHub repository.
سیلورلایت 5 و تاریخ شمسی
.NotSupportedException: The method 'Max' is not supported
This topic provides information about the way in which LINQ queries are composed and executed when you are using the WCF Data Services client and limitations of using LINQ to query a data service that implements the Open Data Protocol (OData). For more information about composing and executing queries against an OData-based data service, see Querying the Data Service (WCF Data Services). Composing LINQ Queries LINQ enables you to compose queries against a collection of objects that implements IEnumerable. Both the Add Service Reference dialog box in Visual Studio and the DataSvcUtil.exe tool are used to generate a representation of an OData service as an entity container class that inherits from DataServiceContext, as well as objects that represent the entities returned in feeds. These tools also generate properties on the entity container class for the collections that are exposed as feeds by the service. Each of these properties of the class that encapsulates the data service return a DataServiceQuery. Because the DataServiceQuery class implements the IQueryable interface defined by LINQ, the WCF Data Services you can compose a LINQ query against feeds exposed by the data service, which are translated by the client library into a query request URI that is sent to the data service on execution. Note: The set of queries expressible in the LINQ syntax is broader than those enabled in the URI syntax that is used by OData data services. A NotSupportedException is raised when the query cannot be mapped to a URI in the target data service. For more information, see the Unsupported LINQ Methods in this topic.