tl; dr - використанняChild
більшParent
переважно в локальному масштабі. Це не тільки допомагає з легкістю для читання, але також необхідно забезпечити, щоб роздільна здатність перевантажених функцій працювала належним чином і сприяла ефективної компіляції.
На місцевому рівні,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Концептуально йдеться про підтримку максимально можливої інформації. Якщо ми переходимо до рівня Parent
, ми фактично просто викреслюємо інформацію про тип, яка могла б бути корисною.
Збереження повної інформації про тип має чотири основні переваги:
- Надає додаткову інформацію компілятору.
- Надає більше інформації для читача.
- Чистіший, більш стандартизований код.
- Робить логіку програми більш змінною.
Перевага 1: Більше інформації для компілятора
Очевидний тип використовується в роздільній роздільній здатності та оптимізації.
Приклад: Перевантажена роздільна здатність методу
main()
{
Parent parent = new Child();
foo(parent);
Child child = new Child();
foo(child);
}
foo(Parent arg) { /* ... */ } // More general
foo(Child arg) { /* ... */ } // Case-specific optimizations
У наведеному вище прикладі обидва foo()
дзвінки працюють , але в одному випадку ми отримуємо кращу перевантажену роздільну здатність методу.
Приклад: Оптимізація компілятора
main()
{
Parent parent = new Child();
var x = parent.Foo();
Child child = new Child();
var y = child .Foo();
}
class Parent
{
virtual int Foo() { return 1; }
}
class Child : Parent
{
sealed override int Foo() { return 2; }
}
У наведеному вище прикладі обидва .Foo()
виклики в кінцевому рахунку викликають один і той же override
метод, який повертається 2
. Просто в першому випадку існує пошук віртуального методу, щоб знайти правильний метод; пошук цього віртуального методу не потрібен у другому випадку з моменту цього методу sealed
.
Подяка @Ben, який надав подібний приклад у своїй відповіді .
Перевага 2: Більше інформації для читача
Знаючи точний тип, тобто Child
надає більше інформації тому, хто читає код, полегшуючи зрозуміти, що робить програма.
Звичайно, може бути , це не має значення для фактичного коду , оскільки обидва parent.Foo();
і child.Foo();
мають сенс, але для кого - то , бачачи код в перший раз, більше інформації це просто корисна.
Крім того, залежно від середовища розробки IDE може надати корисніші підказки та метадані про, Child
ніж Parent
.
Перевага 3: Чистіше, більш стандартизований код
Більшість прикладів коду C #, які я бачив останнім часом var
, і це, в основному, скорочення Child
.
Parent obj = new Child(); // Sub-optimal
Child obj = new Child(); // Optimal, but anti-pattern syntax
var obj = new Child(); // Optimal, clean, patterned syntax "everyone" uses now
Побачення var
заяви про недекларацію просто виглядає; якщо для цього є ситуаційна причина, приголомшливий, але в іншому випадку це виглядає анти-зразком.
// Clean:
var foo1 = new Person();
var foo2 = new Job();
var foo3 = new Residence();
// Staggered:
Person foo1 = new Person();
Job foo2 = new Job();
Residence foo3 = new Residence();
Перевага 4: Більш змінна логіка програми для прототипування
Перші три переваги були великими; це набагато ситуативніше.
Тим не менш, для людей, які використовують код, як і інші, використовують Excel, ми постійно змінюємо наш код. Може бути , нам не потрібно викликати метод , унікальний для Child
в цій версії коду, але ми могли б перепрофілювати або переробити код пізніше.
Перевага системи сильного типу полягає в тому, що вона надає нам певні метадані про нашу логіку програми, роблячи можливості більш зрозумілими. Це неймовірно корисно при прототипуванні, тому краще зберігати його там, де це можливо.
Підсумок
Використання Parent
мес до перевантаженої роздільної здатності методу, гальмує деякі оптимізації компілятора, видаляє інформацію з зчитувача і робить код більш неприємним.
Використання var
- це справді шлях. Це швидко, чисто, з малюнком та допомагає компілятору та IDE правильно виконувати свою роботу.
Важливо : ця відповідь відповідаєParent
порівняноChild
з локальною сферою застосування методу. ПроблемаParent
порівняно зChild
різними для типів повернення, аргументів та класових полів.