یادگیری سی شارپ بعد از جاوا: 5 تفاوت کشف شده
شباهت های زیادی بین جاوا و سی شارپ وجود دارد – هر دو زبان های مدیریت شده با نحوی مشابه هستند که تحت تأثیر C قرار دارند، اما تفاوت های زیادی نیز وجود دارد. در این وبلاگ ما برخی از تمایزات کلیدی را که توسعه دهندگان جاوا هنگام انتقال به C# باید از آنها آگاه باشند، بررسی خواهیم کرد.
1 – قند نحوی
بیایید سه ویژگی زبانی را که سی شارپ برای افزایش خوانایی کد ارائه می دهد، که در جاوا وجود ندارد، بررسی کنیم. این به هیچ وجه یک لیست جامع نیست.
آرگومان های نامگذاری شده و اختیاری
در سی شارپ می توانید از نام پارامتر برای تعیین آرگومان های متد به ترتیب دلخواه استفاده کنید. برای مثال روش زیر را در نظر بگیرید:
static void PrintHello(string name, string surname) =>
Console.WriteLine($"Hello, {name} {surname}!");
فراخوان های زیر از نظر نتیجه یکسان هستند:
PrintHello("John", "Doe");
PrintHello(name: "John", surname: "Doe");
PrintHello(surname: "Doe", name: "John");
علاوه بر این، میتوانید یک مقدار پیشفرض برای پارامتر تعیین کنید، که در این صورت اختیاری میشود:
static void PrintHello(string value="World") =>
Console.WriteLine($"Hello, {value}!");
static void Main(string[] args)
{
PrintHello();
PrintHello("Peggy");
}
دریافت/تنظیم خواص
یک ویژگی در سی شارپ عضوی است که یک رویکرد همه کاره برای دسترسی، تغییر یا محاسبه مقدار یک فیلد خصوصی ارائه می دهد. این یک آنالوگ از گیرنده/تنظیم کننده های معمولی در جاوا با یک نحو خاص و گزینه ای برای پیاده سازی خودکار آنها است.
مثال زیر را با ویژگی های پیاده سازی خودکار در نظر بگیرید:
class Student
{
public string Name {get; init;}
public string? Department {get; set;}
}
در اینجا ما ویژگی های پیاده سازی شده خودکار را اعلام می کنیم. این Name
خاصیت در معرض نمایش قرار می دهد و همچنین تنظیم کننده ای که فقط در زمان اولیه سازی متد قابل استفاده است (init
). این Department
ویژگی هم یک گیرنده و هم یک تنظیم کننده را در معرض نمایش می گذارد. سپس میتوانیم به ویژگیها دسترسی پیدا کرده و مطابق آن اصلاح کنیم:
var student = new Student { Name = "Alice", Department = "Computer Science"};
student.Department = "Chemistry";
Console.WriteLine(student.Department);
Console.WriteLine(student.Name);
Null-Conditional (Elvis) و عملگر Null-Coalescing
برخلاف جاوا، سی شارپ از الویس (?.
) و عملگرهای Null-Coalescing (??
). هدف این عملگرها ساده کردن کار با مقادیر nullable است. به عنوان مثال، این بلوک کد:
string department = null;
if (student != null) {
department = student.Department;
}
قابل جایگزینی با:
string department = student?.Department;
عملگر نول ادغام اجازه می دهد تا جایگزین شود val != null ? val : defaultValue
بیان با val ?? defaultValue
. همچنین می تواند در ترکیب با عملگر Elvis استفاده شود، به عنوان مثال:
Console.WriteLine(student?.Department ?? "Value not known");
2 – استثنائات
در جاوا، به اصطلاح استثناهای چک شده و بدون علامت وجود دارد. استثناهای بررسی شده در زمان کامپایل بررسی می شوند و اگر از روشی استفاده می کنید که یک استثنا علامت زده می کند، باید آن را در کد خود پردازش کنید، در غیر این صورت کامپایل نمی شود. از طرف دیگر استثناهای بدون علامت نباید در کد پردازش شوند. اگر گیر نیاورند، نخی را که روی آن پرتاب می کنند خراب می کنند.
C# مفهوم استثناهای بررسی شده را ندارد و این همیشه به توسعه دهندگان بستگی دارد که چگونه و چه زمانی یک استثنا را پردازش کنند.
3 – IEnumerable & LINQ
رابط IEnumerable در سی شارپ شبیه رابط Iterable در جاوا است. برای پشتیبانی از محاسبات تنبل بر روی اشیاء تکرارپذیر، جاوا 8 یک Stream API جداگانه را معرفی می کند. در سی شارپ، عملکرد مشابه مستقیماً از طریق کلاس Enumerable ارائه می شود.
در اینجا مثالی از استفاده از روش Where از Enumberable برای فیلتر کردن اعداد زوج در سی شارپ آورده شده است:
IEnumerable<int> evenNums = Enumerable.Range(1, 1000)
.Take(5)
.Where(num => num % 2 == 0);
foreach (var num in evenNums)
{
Console.WriteLine(num);
}
در جاوا، همان کد به شکل زیر است:
List<Integer> evenNums = Stream.iterate(1, i -> i + 1)
.limit(5)
.filter(num -> num % 2 == 0)
.toList();
evenNums.forEach(System.out::println);
علاوه بر فراخوانی متدهای پرس و جو همانطور که در مثال بالا نشان داده شده است، سی شارپ قابلیت های Query-Integrated Language (LINQ) را نیز فراهم می کند. این یک فناوری است که اجازه می دهد تا از زبان پرس و جو بر روی اشیاء IEnumberable به طور مستقیم در C# استفاده کنید.
مثال برای فیلتر کردن اعداد زوج در یک نحو به سبک LINQ به شکل زیر خواهد بود:
var nums = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> evenNums = from num in nums
where num % 2 == 0
select num;
foreach (var num in evenNums)
{
Console.WriteLine(num);
}
4 – Async / انتظار
سی شارپ کلمات کلیدی async/wait را برای نوشتن کدهای ناهمزمان به شیوهای خواناتر و متوالیتر فراهم میکند. مثال زیر را در نظر بگیرید، جایی که ما یک روش ناهمزمان را اعلام می کنیم که یک عدد صحیح تصادفی را پس از 2 ثانیه تاخیر ایجاد می کند. ابتدا متد را دو بار فراخوانی می کنیم تا دو عدد صحیح تصادفی تولید کنیم و سپس زمانی که باید مجموع را چاپ کنیم منتظر نتیجه می مانیم:
static async Task<int> RandomIntAsync()
{
await Task.Delay(TimeSpan.FromSeconds(2));
return new Random().Next(0, 100);
}
static async Task Main(string[] args)
{
Task<int> val1 = RandomIntAsync();
Task<int> val2 = RandomIntAsync();
Console.WriteLine(await val1 + await val2);
}
می توانید این وبلاگ پست را بررسی کنید که در آن من تفاوت های نحوه اجرای کد ناهمزمان در C# و جاوا را با جزئیات بیشتر بررسی می کنم.
5 – باطل شدنی
سی شارپ همه متغیرهای نوع مقدار را به صورت پیش فرض غیر قابل تهی در نظر می گیرد. برای اجازه دادن به یک مقدار تهی، نوع باید به طور صریح به عنوان nullable علامت گذاری شود، به سادگی باید یک علامت سوال به تعریف نوع اضافه کرد (به عنوان مثال “int?”). این به توسعه دهندگان اجازه می دهد تا موقعیت هایی را که ممکن است داده ها از دست رفته یا تعریف نشده باشند را پردازش کنند، به عنوان مثال:
class Person
{
public string Name { get; init; }
public int? Age { get; init; }
}
static async Task Main(string[] args)
{
var person = new Person { Name = "Bob"};
if (person.Age == null)
{
Console.WriteLine("Age not specified.");
}
}
علاوه بر انواع مقادیر nullable، می توانید نوع مرجع nullable را مشخص کنید، درست مانند آنچه در بالا در مثال کلاس Student انجام دادیم که در آن رشته Department را به عنوان nullable اعلام کردیم. از لحاظ تاریخی در سی شارپ، همه مراجع به صورت پیش فرض nullable هستند. با این حال، با شروع با C# 8، فرض میشود که مراجع به طور پیشفرض غیر قابل تهی هستند، مگر اینکه به صراحت بیان شده باشد، مشابه نحوه رفتار انواع مقادیر. به دلیل مشکلات مربوط به سازگاری با عقب، این ویژگی به طور پیش فرض فعال نیست.
نتیجه
در اینجا مروری کوتاه بر برخی (اما نه همه) تفاوت های عمده بین C# و جاوا داشتیم. امیدواریم این یک نقطه شروع در هنگام تغییر از جاوا به C# باشد!