مقدمهای بر NET MAUI.
An Introduction to .NET MAUI For Mobile Development
.NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating native mobile and desktop apps with C# and XAML.
.NET MAUI is open-source and is the evolution of Xamarin.Forms, extended from mobile to desktop scenarios, with UI controls rebuilt from the ground up for performance and extensibility. If you've previously used Xamarin.Forms to build cross-platform user interfaces, you'll notice many similarities with .NET MAUI. However, there are also some differences. Using .NET MAUI, you can create multi-platform apps using a single project, but you can add platform-specific source code and resources if necessary. One of the key aims of .NET MAUI is to enable you to implement as much of your app logic and UI layout as possible in a single code-base.
0:00 - Setup Visual Studio and MAUI Project
00:16:25 - Create MAUI Pages with C#
00:27:42 - Create MAUI Pages with XAML
00:32:28 - Explore MAUI Layouts
00:39:38 - Static Shared Resources
00:44:36 - Platform Specific Values
00:50:11 - Page Navigation
کتابخانه NetTopologySuite
لیست تغییرات جدید ASP.NET Core 5.0
عناوین برخی از امکانات و بهبود ها
- MVC model binding improvements, including support for C# 9 record types
- Blazor Server & Blazor WebAssembly support and improvements
- Built-in OpenAPI and Swagger UI support for Web APIs
- SignalR Hub filters and parallel Hub invocations
- Azure AD authentication with MIcrosoft.Identity.Web
- Auto browser refresh with dotnet watch
- HTTP/2 and gRPC performance improvements
0.Visual Studio 2017 15.9 منتشر شد
Summary of Notable New Features in 15.9
- You can now import and export an installation configuration file that specifies which workloads and components should be installed with an instance of Visual Studio.
- We have improved the debugging experience for NuGet packages using the new symbol package format (.snupkg).
- Step back in debugger is now available in C++ for Enterprise customers.
- C++ IntelliSense now responds to changes in the remote environment for both CMake and MSBuild projects targeting Linux.
- We have made updates to UWP Desktop Bridge framework packages and added support for ARM64 C++ Native Desktop scenarios.
- We added support for the range-v3 library with the MSVC 15.9 compiler.
- We fixed several bugs in the F# compiler and F# tools.
- Language service support for new TypeScript features for semantic file renaming and project references.
- Improved Node.js development by updating Vue.js templates and adding support for unit testing using the Jest framework.
- We added SharePoint 2019 project templates, so you can migrate existing SharePoint 2013 and 2016 projects to SharePoint 2019.
- Visual Studio Tools for Xamarin now supports Xcode 10.
- We made improvements to the Xamarin.Android build performance.
- We have added and improved features for Universal Windows Platform developers, including ARM64 support, the latest preview SDK, better debugging of Desktop Bridge applications, and XAML Designer improvements.
- Substantial improvements were made to the experience of using authenticated package feeds.
- There is now support for lock file to enable repeatable restore for PackageReference based projects.
- We have added support for the new license format for NuGet packages.
- We have introduced NuGet client policies in Visual Studio which enables you to lock down environments such that only trusted packages can be installed.
- We made the use of .NET Core within Visual Studio more predictable.
Top Issues Fixed in 15.9
- No way to change "Find All References" background color.
- "Visual C++ Resource Editor Package" load failed.
- VS2017 v15.8 Build does not start if XAML files are not manually saved first.
- Installation failed - manifest signature verification failed.
- Update 15.8.6 breaks Installer Projects.
- Scrolling up with the arrow key causes Visual Studio to page up.
- After updating to 15.8.1, data tip does not show when debugging.
- System.InvalidProgramException: Common Language Runtime detected an invalid program..
- Solution Explorer does not remain pinned after closing Visual Studio.
- Navigation bar in editor has trouble handling long method names.
C# 6 - String Interpolation
در C# 11، متن درون {} یک عبارت string interpolation، میتواند در طی چند سطر نیز تعریف شود و متن بین {} به صورت یک عبارت #C تفسیر میشود. در اینجا هر عبارت معتبر #C ای را میتوان بکار برد. در این حالت تعریف عبارات LINQ و pattern matching switch expressions سادهتر میشوند. برای مثال:
namespace CS11Tests; public static class NewLinesStringInterpolations { public static void Test() { var month = 8; var season = $"The season is {month switch { >= 1 and <= 3 => "spring", >= 4 and <= 6 => "summer", >= 7 and <= 9 => "autumn", 10 or 11 or 12 => "winter", _ => "Wrong month number", }}."; Console.WriteLine(season); int[] numbers = { 1, 2, 3, 4, 5, 6 }; var message = $"The reversed even values of {nameof(numbers)} are {string.Join(", ", numbers.Where(n => n % 2 == 0).Reverse())}."; Console.WriteLine(message); } }
- DateTime.Now = Cannot provide the value: host value not found
- MSVC codegen error vector reverse_iterator x64 C++17 debug build
- C2440 error building atlenc.h with /permissive- in VS 16.4 Preview 1
- Last Visual Studio update broke NTLM authentication on Android (seems like new version of Momo would be a reason)
- Visual Studio 16.3.1 fails at compiling template code (e.g. from Basler Pylon SDK)
- Using TypeScript 3.7 for IntelliSense
- XCode 11.3 is too new all of a sudden after update to 8.4
- You uploaded an APK or Android App Bundle with invalid or missing signing information for some of its files. You need to create a valid signed APK or Android App Bundle.
- Unable to Run UWP project
- JavaScript IntelliSense not working after update 16.4.1
- Xib : Xcode is to new(rendering problem when using custom components)
- Storyboard error: 'Xcode is too new'
- Stability improvements for debugging watchOS applications.
- Adds Xcode 11.3 SDK support.
- Fixed crash when fstack-protector-strong flag is enabled.
- Fixed some inconsistent behavior with Debugger.
Security Advisory Notice
CVE-2020-0602 ASP.NET Core Denial of Service Vulnerability
CVE-2020-0603 ASP.NET Core Remote Code Execution Vulnerability
CVE-2020-0605 .NET Core Remote Code Execution Vulnerability
CVE-2020-0606 .NET Core Remote Code Execution Vulnerability
Established leaders (in blue in the chart and including Java, C#, and JavaScript) which are "common in paying organisations and show a high demand globally". Followers (in green) such as PHP, Python, and Ruby were found to "pay on average the same salaries, although their is 50% less demand for them". Finally there are a group referred to as Niche (orange) which "show very low demand and salaries almost 60% lower".
معرفی عملگر Hat
برای دسترسی به آخرین عضو یک آرایه عموما از روش زیر استفاده میشود:
var integerArray = new int[3]; var lastItem = integerArray[integerArray.Length - 1];
var integerList = integerArray.ToList(); integerList.Last();
var secondToLast = integerArray[integerArray.Length - 2];
این شمردنهای از آخر در C# 8.0 توسط ارائهی عملگر hat یا همان ^ که پیشتر کار xor را انجام میداد (و البته هنوز هم در جای خودش همین مفهوم را دارد)، میسر شدهاست:
var lastItem = integerArray[^1];
نکتهی مهم: کسانیکه شروع به آموزش برنامه نویسی میکنند، مدتی طول میکشد تا عادت کنند که اولین ایندکس یک آرایه از صفر شروع میشود. در اینجا باید درنظر داشت که با بکارگیری «عملگر کلاه»، آخرین ایندکس یک آرایه از «یک» شروع میشود و نه از صفر. برای نمونه در مثال زیر به خوبی تفاوت بین ایندکس از ابتدا و ایندکس از انتها را میتوانید مشاهده کنید:
var words = new string[] { // index from start index from end "The", // 0 ^9 "quick", // 1 ^8 "brown", // 2 ^7 "fox", // 3 ^6 "jumped", // 4 ^5 "over", // 5 ^4 "the", // 6 ^3 "lazy", // 7 ^2 "dog" // 8 ^1 }; // 9 (or words.Length) ^0
در حالت کلی ایندکس n^ معادل sequence.Length - n است. بنابراین sequence[^0] به معنای sequence[sequence.Length] است و هر دو مورد یک index out of range exception را صادر میکنند.
IDE نیز با فعال سازی C# 8.0، زمانیکه به قطعه کد زیر میرسد، زیر words.Length - 1 خط کشیده و پیشنهاد میدهد که بهتر است از 1^ استفاده کنید:
Console.WriteLine($"The last word is {words[words.Length - 1]}");
معرفی نوع جدید Index
در C# 8.0 زمانیکه مینویسم 1^، در حقیقت قطعه کد زیر را ایجاد کردهایم:
var index = new Index(value: 1, fromEnd: true); Index indexStruct = ^1; var indexShortHand = ^1;
در سطر اول، پارامتر fromEnd نیز قابل تعریف است. این fromEnd با مقدار true، همان عملگر ^ در اینجا است و عدم ذکر این عملگر به معنای false بودن آن است:
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Console.WriteLine(a[a.Length – 2]); // will write 8 on console. Console.WriteLine(a[^2]); // will write 8 on console. Index i5 = 5; Console.WriteLine(a[i5]); //will write 5 on console. Index i2fromEnd = ^2; Console.WriteLine(a[i2fromEnd]); // will write 8 on console.
روش دسترسی به بازهای از اعضای یک آرایه تا پیش از C# 8.0
فرض کنید آرایهای از اعداد بین 1 تا 10 را به صورت زیر ایجاد کردهاید:
var numbers = Enumerable.Range(1, 10).ToArray();
var (start, end) = (1, 7); var length = end - start; // Using LINQ var subset1 = numbers.Skip(start).Take(length); // Or using Array.Copy var subset2 = new int[length]; Array.Copy(numbers, start, subset2, 0, length);
روش دسترسی به بازهای از اعضای یک آرایه در C# 8.0
در C# 8.0 برای دسترسی به بازهای از عناصر یک آرایه میتوان از range expression که به صورت x..y نوشته میشود، استفاده کرد. در ادامه، مثالهایی را از کاربردهای عبارت .. ملاحظه میکنید:
var myArray = new string[] { "Item1", "Item2", "Item3", "Item4", "Item5" };
var fromIndexToX = myArray[1..3]; // = [Item2, Item3]
var fromIndexToXFromTheEnd = myArray[1..^1]; // = [ "Item2", "Item3", "Item4" ]
var fromAnIndexToTheEnd = myArray[1..]; // = [ "Item2", "Item3", "Item4", "Item5" ]
var fromTheStartToAnIndex = myArray[..3]; // = [ "Item1", "Item2", "Item3" ]
var entireRange = myArray[..]; // = [ "Item1", "Item2", "Item3", "Item4", "Item5" ]
مثالی دیگر: بازنویسی یک حلقهی for با foreach
حلقهی for زیر را
var myArray = new string[] { "Item1", "Item2", "Item3", "Item4", "Item5" }; for (int i = 1; i <= 3; i++) { Console.WriteLine(myArray[i]); }
foreach (var item in myArray[1..4]) // = [ "Item2", "Item3", "Item4" ] { Console.WriteLine(item); }
یعنی ابتدای آن inclusive است و انتهای آن exclusive
چند مثال کاربردی و متداول از بازهها
using System; using System.Linq; namespace ConsoleApp { class Program { private static readonly int[] _numbers = Enumerable.Range(1, 10).ToArray(); static void Main() { var skip2CharactersAndTake2Characters = _numbers[2..4]; // صرفنظر کردن از دو عنصر اول و سپس انتخاب دو عنصر var skipFirstAndLastCharacter = _numbers[1..^1]; // صرفنظر کردن از دو عنصر اول و آخر var last3Characters = _numbers[^3..]; // انتخاب بازهای شامل سه عنصر آخر var first4Characters = _numbers[0..4]; // دریافت بازهای از 4 عنصر اول var rangeStartFrom2 = _numbers[2..]; // دریافت بازهای شروع شده از المان دوم تا آخر var skipLast3Characters = _numbers[..^3]; // صرفنظر کردن از سه المان آخر var rangeAll = _numbers[..]; // انتخاب کل بازه } } }
معرفی نوع جدید Range
در C# 8.0 زمانیکه مینویسم 4..1، در حقیقت قطعه کد زیر را ایجاد کردهایم:
var range = new Range(1, 4); Range rangeStruct = 1..4; var rangeShortHand = 1..4;
یک مثال: استفاده از نوع جدید Range به عنوان پارامتر یک متد
using System; using System.Linq; namespace ConsoleApp { class Program { private static readonly int[] _numbers = Enumerable.Range(1, 10).ToArray(); static void Print(Range range) => Console.WriteLine($"{range} => {string.Join(", ", _numbers[range])}"); static void Main() { Print(1..3); // 1..3 => 2, 3 Print(..3); // 0..3 => 1, 2, 3 Print(3..); // 3..^0 => 4, 5, 6, 7, 8, 9, 10 Print(1..^1); // 1..^1 => 2, 3, 4, 5, 6, 7, 8, 9 Print(^2..^1); // ^2..^1 => 9 } } }
مثالی دیگر: استفاده از Range به عنوان جایگزینی برای متد String.Substring
از Range میتوان برای کار بر روی رشتهها و انتخاب قسمتی از آنها نیز استفاده کرد:
Console.WriteLine("123456789"[1..4]); // Would output 234
var helloWorldStr = "Hello, World!"; var hello = helloWorldStr[..5]; Console.WriteLine(hello); // Output: Hello var world = helloWorldStr[7..]; Console.WriteLine(world); // Output: World! var world2 = helloWorldStr[^6..]; // Take the last 6 characters Console.WriteLine(world); // Output: World!
سؤال: زمانیکه بازهای از یک آرایه را انتخاب میکنیم، آیا یک آرایهی جدید ایجاد میشود، یا هنوز به همان آرایهی قبلی اشاره میکند؟
پاسخ: یک آرایهی جدید ایجاد میشود؛ اما میتوان با فراخوانی متد ()array.AsSpan پیش از انتخاب یک بازه، بازهای را تولید کرد که دقیقا به همان آرایهی اصلی اشاره میکند و یک کپی جدید نیست:
var arr = (new[] { 1, 4, 8, 11, 19, 31 }).AsSpan(); var range = arr[2..5]; ref int elt1 = ref range[1]; elt1 = -1; int copiedElement = range[2]; copiedElement = -2; Console.WriteLine($"range[1]: {range[1]}, range[2]: {range[2]}"); // output: range[1]: -1, range[2]: 19 Console.WriteLine($"arr[3]: {arr[3]}, arr[4]: {arr[4]}"); // output: arr[3]: -1, arr[4]: 19