Target Typing در C# 9.0
مشکلی که بعضیها با واژهی کلیدی var دارند، این است که اندکی خوانایی کدها را کاهش میدهد و در این حالت بلافاصله مشخص نیست که نوع شیء در حال استفاده چیست. در C# 9.0 برای این دسته از برنامه نویسها راه حل دیگری را پیشنهاد دادهاند: نوع ابتدایی را مشخص کنید، اما نیازی به ذکر نوع پس از واژهی کلیدی new نیست و همانند var، خود کامپایلر آنرا حدس خواهد زد! برای توضیح آن دو کلاس سادهی زیر را درنظر بگیرید:
public class Person { public string FirstName { get; set; } } public class PersonWithCtor { public PersonWithCtor(string firstName) { this.FirstName = firstName; } public string FirstName { get; set; } }
Person person = new Person();
var person = new Person();
Person person = new();
Target Typing و پارامترهای سازندهی کلاسها در C# 9.0
در مثال فوق، کلاس PersonWithCtor به همراه یک سازندهی پارامتردار تعریف شدهاست. در این حالت Target Typing آن به صورت زیر خواهد بود:
Person person = new("User 1");
var personList = new List<Person> { new ("User 1"), new ("User 2"), // ... };
public void Adopt(Person p) { //... } public void CallerMethod() { this.Adopt(new Person("User 1")); // C# 9.0 this.Adopt(new("User 1")); }
XmlReader.Create(reader, new XmlReaderSettings() { IgnoreWhitespace = true }); // C# 9.0 XmlReader.Create(reader, new() { IgnoreWhitespace = true });
Target Typing و استفاده از خواص کلاسها در C# 9.0
در همان مثال اول، اگر بخواهیم خاصیت FirstName را مقدار دهی کنیم و همچنین از Target Typing نیز استفاده کنیم ... روش زیر کامپایل نخواهد شد:
Person person = new { FirstName = "User 2" };
Person person = new() { FirstName = "User 2" };
امکان استفادهی از Target typing با فیلدها در C# 9.0
امکان تعریف var با فیلدهای یک کلاس در زبان #C وجود ندارد. به همین جهت مجبور هستیم یک چنین تعاریف طولانی را در سطح کلاسها داشته باشیم:
private ConcurrentDictionary<string, ObservableList<Cat>> _catsBefore = new ConcurrentDictionary<string, ObservableList<Cat>>();
private ConcurrentDictionary<string, ObservableList<Cat>> _cats = new(); // C# 9.0
public ObservableCollection<Friend> Friends { get; } = new();
امکان ترکیب null-coalescing operator با target typing در C# 9.0
null-coalescing operator یا همان ?? به این معنا است که اگر متغیر سمت چپ آن نال نبود، همان مقدار درنظر گرفته شود و اگر نال بود، متغیر سمت راست آن بازگشت داده شود. در این حالت مثال زیر را در نظر بگیرید که در آن سگ و گربه از نوع پایهی حیوان تعریف شدهاند:
public interface IAnimal { } public class Dog : IAnimal { } public class Cat : IAnimal { }
Cat cat = null; Dog dog = new(); IAnimal animal = cat ?? dog;
دانستنیهایی در مورد Target Typing
- نوشتن ()throw new مجاز است و نوع پیشفرض آن، System.Exception در نظر گرفته میشود.
- در حالت کار با tuples، نوشتن new اضافی است:
(int a, int b) t = new(1, 2); // "new" is redundant
(int a, int b) t = new(); // OK; same as (0, 0)
محدودیتهای Target Typing در C# 9.0
- امکان نوشتن ()var dog = new وجود ندارد؛ چون نوع سمت راست این انتساب دیگر قابل حدس زدن نیست. نمونهی دیگر آن anonymous type properties است؛ مانند new { Prop = new() } که در آن برای مثال نوع خاصیت Prop قابل حدس زدن نیست.
- target typing با binary operators قابل استفاده نیست.
- به عنوان ref قابل استفاده نیست.