I have been using Windows operating system from the beginning. When I first started using computer Windows XP was the latest operating system and it was amazing. After few years I started my career as a Java developer and in my office also I have been using Windows only.
After few years Windows Vista got released and I suffered with it for few months and then Microsoft released Windows 7 which is the best Windows operating system IMO. And then they released Windows 8 which I don’t like much. Recently they released Windows 10 and I have upgraded from Windows 8.1 to Windows 10. Windows 10 is certainly better than Windows 8 but it still sucks compared to Windows 7.
کتاب OWIN Succinctly
OWIN Succinctly, has just been released by Syncfusion, within their “succinctly” series of eBooks.
jQuery 3.6.0 منتشر شد
jQuery 3.6.0 has been released! In jQuery 3.5.0, the major change was a security fix for the html prefilter. This release does not include a security fix, but does have some good bug fixes and improvements. We still have our eyes on a jQuery 4.0 release, but until then we will continue to support the 3.x branch and address important issues.
کتابخانه jquery.wanker
ASP.NET Core 3.0 Preview 9 منتشر شد
To get started with ASP.NET Core in .NET Core 3.0 Preview 9 install the .NET Core 3.0 Preview 9 SDK.
If you’re on Windows using Visual Studio, install the latest preview of Visual Studio 2019.
.NET Core 3.0 Preview 9 requires Visual Studio 2019 16.3 Preview 3 or later.
Tuple چیست؟
هدف از کار با Tupleها، عدم تعریف یک کلاس جدید به همراه خواص آن، جهت بازگشت بیش از یک مقدار از یک متد، توسط وهلهای از این کلاس جدید میباشد. برای مثال اگر بخواهیم از متدی، دو مقدار شهر و ناحیه را بازگشت دهیم، یک روش آن، ایجاد کلاس مکان زیر است:
public class Location { public string City { get; set; } public string State { get; set; } public Location(string city, string state) { City = city; State = state; } }
var location = new Location("Lake Charles","LA");
var location = new Tuple<string,string>("Lake Charles","LA"); // Print out the address var address = $"{location.Item1}, {location.Item2}";
مشکلات نوع Tuple در نگارشهای قبلی دات نت
هرچند Tuples از زمان دات نت 4 در دسترس هستند، اما دارای این کمبودها و مشکلات میباشند:
static Tuple<int, string, string> GetHumanData() { return Tuple.Create(10, "Marcus", "Miller"); }
var data = GetHumanData(); Console.WriteLine("What is this value {0} or this {1}", data.Item1, data.Item3);
ج) Tuples در دات نت 4، صرفا یک کتابخانهی اضافه شدهی به فریم ورک بوده و زبانهای دات نتی، پشتیبانی توکاری را از آنها جهت بهبود و یا ساده سازی تعریف آنها، ارائه نمیدهند.
ایجاد Tuples در C# 7
برای ایجاد Tuples در سی شارپ 7، از پرانتزها به همراه ذکر نام و نوع پارامترها استفاده میشود.
(int x1, string s1) = (3, "one"); Console.WriteLine($"{x1} {s1}");
دسترسی به این مقادیر نیز همانند متغیرهای معمولی است.
اگر سعی کنیم این قطعه کد را کامپایل نمائیم، با خطای ذیل متوقف خواهیم شد:
error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
PM> install-package System.ValueTuple
تعاریف متغیرهای بازگشتی، خارج از پرانتزها هم میتوانند صورت گیرند:
int x2; string s2; (x2, s2) = (42, "two"); Console.WriteLine($"{x2} {s2}");
بازگشت Tuples از متدها
متد ذیل، دو خروجی نتیجه و باقیماندهی تقسیم دو عدد صحیح را باز میگرداند:
static (int, int) Divide(int x, int y) { int result = x / y; int reminder = x % y; return (result, reminder); }
در ادامه نحوهی استفادهی از این متد را مشاهده میکنید:
(int result, int reminder) = Divide(11, 3); Console.WriteLine($"{result} {reminder}");
در اینجا امکان استفادهی از var نیز برای تعریف نوع متغیرهای دریافتی از یک Tuple نیز وجود دارد و کامپایلر به صورت خودکار نوع آنها را بر اساس نوع خروجی tuple مشخص میکند:
(var result1, var reminder1) = Divide(11, 3); Console.WriteLine($"{result1} {reminder1}");
var (result1, reminder1) = Divide(11, 3);
و یا برای نمونه متد GetHumanData دات نت 4 ابتدای بحث را به صورت ذیل میتوان در C# 7 بازنویسی کرد:
static (int, string, string) GetHumanData() { return (10, "Marcus", "Miller"); }
(int Age, string FirstName, string LastName) results = GetHumanData(); Console.WriteLine(results.Age); Console.WriteLine(results.FirstName); Console.WriteLine(results.LastName);
پشت صحنهی Tuples در C# 7
همانطور که عنوان شد، برای اینکه بتوانید قطعه کدهای فوق را کامپایل کنید، نیاز به بستهی نیوگت System.ValueTuple است. در حقیقت کامپایلر خروجی متد فوق را به نحو ذیل تفسیر میکند:
ValueTuple<int, int> tuple1 = Divide(11, 3);
(int, int) n = (1,1); System.Console.WriteLine(n.Item1);
ValueTuple<int, int> n = new ValueTuple<int, int>(1, 1); System.Console.WriteLine(n.Item1);
- همچنین در اینجا محدودیتی از لحاظ تعداد پارامترهای ذکر شدهی در یک Tuple وجود ندارد.
(int,int,int,int,int,int,int,(int,int))
مفهوم Tuple Literals
همانند نگارشهای پیشین دات نت، خروجی یک Tuple را میتوان به یک متغیر از نوع var و یا ValueType نیز نسبت داد:
var tuple2 = ("Stephanie", 7); Console.WriteLine($"{tuple2.Item1}, {tuple2.Item2}");
به علاوه در سی شارپ 7 میتوان برای اعضای یک Tuple نام نیز تعریف کرد که به آنها Tuple literals گویند:
var tuple3 = (Name: "Matthias", Age: 6); Console.WriteLine($"{tuple3.Name} {tuple3.Age}");
و یا هنگام تعریف نوع خروجی، میتوان نام پارامترهای متناظر را نیز ذکر کرد که به آن named elements هم میگویند:
static (int radius, double area) CalculateAreaOfCircle(int radius) { return (radius, Math.PI * Math.Pow(radius, 2)); }
var circle = CalculateAreaOfCircle(2); Console.WriteLine($"A circle of radius, {circle.radius}," + $" has an area of {circle.area:N2}.");
مفهوم Deconstructing Tuples
مفهوم deconstruction که در ابتدای بحث عنوان شد صرفا مختص به Tuples نیست. در C# 7 میتوان مشخص کرد که چگونه یک نوع خاص، به اجزای آن تجزیه شود. برای مثال کلاس شخص ذیل را درنظر بگیرید:
class Person { private readonly string _firstName; private readonly string _lastName; public Person(string firstname, string lastname) { _firstName = firstname; _lastName = lastname; } public override String ToString() => $"{_firstName} {_lastName}"; public void Deconstruct(out string firstname, out string lastname) { firstname = _firstName; lastname = _lastName; } }
- علت تعریف این دو خروجی هم به constructor و یا سازندهی کلاس بر میگردد که دو ورودی را دریافت میکند. اگر یک کلاس چندین سازنده داشته باشد، به همان تعداد میتوان متد Deconstruct تعریف کرد؛ به همراه خروجیهایی متناظر با نوع پارامترهای سازندهها.
- علت استفادهی از نوع خروجی out نیز این است که در #C نمیتوان چندین overload را صرفا بر اساس نوع خروجیهای متفاوت متدها تعریف کرد.
- متد Deconstruct به صورت خودکار در زمان تجزیهی یک شیء به یک tuple فراخوانی میشود. در مثال زیر، شیء p1 به یک Tuple تجزیه شدهاست و این تجزیه بر اساس متد Deconstruct این کلاس مفهوم پیدا میکند:
var p1 = new Person("Katharina", "Nagel"); (string first, string last) = p1; Console.WriteLine($"{first} {last}");
امکان تعریف متد Deconstruct، به صورت یک متد الحاقی
روش اول تعریف متد ویژهی Deconstruct را در مثال قبل، در داخل کلاس اصلی مشاهده کردید. روش دیگر آن، استفادهی از متدهای الحاقی است که در این مورد خاص نیز مجاز است:
public class Rectangle { public Rectangle(int height, int width) { Height = height; Width = width; } public int Width { get; } public int Height { get; } } public static class RectangleExtensions { public static void Deconstruct(this Rectangle rectangle, out int height, out int width) { height = rectangle.Height; width = rectangle.Width; } }
اکنون امکان انتساب وهلهای از این کلاس به یک Tuple وجود دارد:
var r1 = new Rectangle(100, 200); (int height, int width) = r1; Console.WriteLine($"height: {height}, width: {width}");
امکان جایگزین کردن Anonymous types با Tuples
قطعه کد ذیل را در نظر بگیرید:
List<Employee> allEmployees = new List<Employee>() { new Employee { ID = 1L, Name = "Fred", Salary = 50000M }, new Employee { ID = 2L, Name = "Sally", Salary = 60000M }, new Employee { ID = 3L, Name = "George", Salary = 70000M } }; var wellPaid = from oneEmployee in allEmployees where oneEmployee.Salary > 50000M select new { EmpName = oneEmployee.Name, Income = oneEmployee.Salary };
var wellPaid = from oneEmployee in allEmployees where oneEmployee.Salary > 50000M orderby oneEmployee.Salary descending select (EmpName: oneEmployee.Name, Income: oneEmployee.Salary); var highestPaid = wellPaid.First().EmpName;
سایر کاربردهای Tuples
از Tuples صرفا برای تعریف چندین خروجی از یک متد استفاده نمیشود. در ذیل نحوهی استفادهی از آنها را جهت تعریف کلید ترکیبی یک شیء دیکشنری و یا استفادهی از آنها را در آرگومان جنریک یک متد async هم مشاهده میکنید:
public Task<(int index, T item)> FindAsync<T>(IEnumerable<T> input, Predicate<T> match) { var dictionary = new Dictionary<(int, int), string>(); throw new NotSupportedException(); }
VSCode برای توسعه دهندگان سیشارپ
VSCode for the C# Developer - Tim Corey - NDC London 2023
VSCode is a nimble editor that can do just about anything. In this session, we will set up and configure VSCode for use in C# development. Then we will use it to build, debug, and deploy a small .NET Core web application to Azure.
Along the way, we will go over a list of the top C#-focused plugins for VSCode. Whether you are just getting started with VSCode or you are used to VSCode but want to start building C# projects, this session will get you up to speed fast.
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders