tl; dr - Sử dụngChild
hơnParent
là thích hợp hơn trong phạm vi địa phương. Nó không chỉ giúp dễ đọc mà còn cần đảm bảo rằng độ phân giải phương thức quá tải hoạt động đúng và giúp cho phép biên dịch hiệu quả.
Trong phạm vi địa phương,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Về mặt khái niệm, đó là về việc duy trì thông tin loại nhất có thể. Nếu chúng tôi hạ cấp xuống Parent
, về cơ bản, chúng tôi chỉ loại bỏ thông tin loại có thể hữu ích.
Giữ lại thông tin loại hoàn chỉnh có bốn ưu điểm chính:
- Cung cấp thêm thông tin cho trình biên dịch.
- Cung cấp thêm thông tin cho người đọc.
- Mã sạch hơn, chuẩn hơn.
- Làm cho logic chương trình trở nên đột biến hơn.
Ưu điểm 1: Thêm thông tin cho trình biên dịch
Loại rõ ràng được sử dụng trong độ phân giải phương thức quá tải và tối ưu hóa.
Ví dụ: Độ phân giải phương thức quá tải
main()
{
Parent parent = new Child();
foo(parent);
Child child = new Child();
foo(child);
}
foo(Parent arg) { /* ... */ } // More general
foo(Child arg) { /* ... */ } // Case-specific optimizations
Trong ví dụ trên, cả hai foo()
cuộc gọi đều hoạt động , nhưng trong một trường hợp, chúng ta có được độ phân giải phương thức quá tải tốt hơn.
Ví dụ: Tối ưu hóa trình biên dịch
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; }
}
Trong ví dụ trên, cả hai .Foo()
cuộc gọi cuối cùng đều gọi cùng một override
phương thức trả về 2
. Chỉ trong trường hợp đầu tiên, có một phương thức tra cứu ảo để tìm phương thức đúng; tra cứu phương thức ảo này không cần thiết trong trường hợp thứ hai kể từ phương thức đó sealed
.
Tín dụng cho @Ben người đã cung cấp một ví dụ tương tự trong câu trả lời của mình .
Ưu điểm 2: Thêm thông tin cho người đọc
Biết loại chính xác, nghĩa là Child
, cung cấp thêm thông tin cho bất kỳ ai đang đọc mã, giúp dễ dàng hơn để xem chương trình đang làm gì.
Chắc chắn, có lẽ nó không quan trọng với mã thực tế vì cả hai parent.Foo();
và child.Foo();
có ý nghĩa, nhưng đối với một người nào đó nhìn thấy mã cho lần đầu tiên, biết thêm thông tin là chỉ đơn giản hữu ích.
Ngoài ra, tùy thuộc vào môi trường phát triển của bạn, IDE có thể cung cấp nhiều công cụ và siêu dữ liệu hữu ích Child
hơn Parent
.
Ưu điểm 3: Mã sạch hơn, chuẩn hơn
Hầu hết các ví dụ mã C # mà tôi đã thấy gần đây sử dụng var
, về cơ bản là tốc ký 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
Nhìn thấy một var
tuyên bố không khai báo chỉ nhìn ra; nếu có một lý do tình huống cho nó, tuyệt vời, nhưng nếu không thì nó có vẻ chống mẫu.
// 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();
Ưu điểm 4: Logic chương trình đột biến hơn cho tạo mẫu
Ba lợi thế đầu tiên là những lợi thế lớn; cái này nhiều tình huống hơn.
Tuy nhiên, đối với những người sử dụng mã như những người khác sử dụng Excel, chúng tôi liên tục thay đổi mã của mình. Có lẽ chúng ta không cần phải gọi một phương thức độc đáo để Child
trong này phiên bản mã, nhưng chúng ta có thể sử dụng lại hoặc làm lại các mã sau.
Ưu điểm của một hệ thống loại mạnh là nó cung cấp cho chúng tôi một số dữ liệu meta nhất định về logic chương trình của chúng tôi, làm cho các khả năng trở nên rõ ràng hơn. Điều này cực kỳ hữu ích trong việc tạo mẫu, vì vậy tốt nhất là giữ nó ở nơi có thể.
Tóm lược
Sử dụng Parent
làm rối quá trình giải quyết phương thức quá tải, ức chế một số tối ưu hóa trình biên dịch, loại bỏ thông tin khỏi đầu đọc và làm cho mã xấu hơn.
Sử dụng var
thực sự là con đường để đi. Nó nhanh chóng, gọn gàng, khuôn mẫu và giúp trình biên dịch và IDE thực hiện công việc của họ đúng cách.
Quan trọng : Câu trả lời này là vềParent
so vớiChild
trong phạm vi cục bộ của phương thức. Vấn đềParent
so vớiChild
rất khác nhau đối với kiểu trả về, đối số và trường lớp.