Có cách nào để thực hiện việc này trong C# không? Tôi biết rằng lớp con sẽ gọi hàm tạo của lớp bậc trên trước khi gọi hàm tạo riêng của nó, nhưng nếu tôi có một số mã trên lớp cha mà chỉ nên được thực thi sau khi tất cả các hàm tạo lớp con đã được gọi?Làm cách nào để thực thi một số mã trong một siêu lớp sau khi tất cả các lớp con đã được xây dựng?
Làm cách nào để thực thi một số mã trong một siêu lớp sau khi tất cả các lớp con đã được xây dựng?
Trả lời
Một cách để đạt được điều này sẽ là để đi cho một cấu trúc 2 giai đoạn và khởi tạo. Vì vậy, bạn xây dựng các trường hợp và sau đó gọi một phương thức khởi mà gọi các lớp cơ sở Initialize theo thứ tự thích hợp
class MyBase
{
// Only if need to do some core initialization
public MyBase()
{
}
public virtual Initialize()
{
// do some initialization stuff here
}
}
class MyDerived : MyBase
{
// Only if need to do some core initialization
public MyDerived()
{
}
public override Initialize()
{
// do some initialization stuff here
// Call the base class initialization function
base.Initialize();
}
}
Nếu bạn thực hiện tạo/khởi tạo hai lần, tôi sẽ tư vấn bằng cách sử dụng một phương pháp nhà máy hoặc nhà máy Asbtract để đảm bảo rằng ngữ nghĩa khởi tạo không được lan truyền trên tất cả các mã – LBushkin
Ok, đó không phải là chính xác những gì tôi có nghĩa là nhưng nó kinda giúp tôi giải quyết vấn đề, ty –
class A : B
{
public A() : base()
{
base.doSomething();
}
}
class B : C
{
public B() : base()
{
}
public void doSomething() { /* ... */ }
}
class C
{
public C() { /* ... */ }
}
Thực hiện theo thứ tự nên là:
- C :: ctor()
- B :: ctor()
- A :: ctor()
- B :: doSomething ()
Như tôi đã nói, phương thức nên được thực hiện trong lớp cha, không phải trong lớp con, bạn chỉ cần gọi phương thức superclass trong lớp con. –
Tôi nghi ngờ OP đang tìm kiếm giải pháp trong đó lớp cơ sở có thể đảm bảo rằng một số khởi chạy chạy sau khi loại được khởi tạo đầy đủ. Nếu không, mỗi tác giả lớp dẫn xuất phải đảm bảo gọi logic khởi tạo cần thiết. – LBushkin
Thats chính xác những gì tôi cần: ( –
Tôi không chắc chắn ý của bạn là gì - bạn không thể gọi mã trong lớp siêu ở cuối lớp con cuối cùng của chúng tôi structor? Hoặc bạn có thể gọi nó trực tiếp sau khi instantiation.
class Program
{
static void Main(string[] args)
{
SubSub obj = new SubSub();
//obj.DoStuff();
Console.ReadLine();
}
}
class Super
{
public Super()
{
Console.WriteLine("Constructing Super");
}
public void DoStuff()
{
Console.WriteLine("Doin' stuff");
}
}
class Sub : Super
{
public Sub()
{
Console.WriteLine("Constructing Sub");
}
}
class SubSub : Sub
{
public SubSub()
{
Console.WriteLine("Constructing SubSub");
DoStuff();
}
}
Sản lượng này sẽ:
Constructing Super
Constructing Sub
Constructing SubSub
Doin' stuff
Điều tôi ngụ ý là mã có thể được thực thi sau khi hoàn thành việc xây dựng đối tượng trong lớp cha, lớp con không nên biết về nó. –
Bạn có thể làm những điều sau đây, nhưng nó là rủi ro (xem Chỉnh sửa của tôi dưới đây):
public class Parent
{
public Parent()
{
Initialize();
}
protected virtual void Initialize()
{
// do stuff
}
}
public class Child : Parent
{
protected override void Initialize()
{
// do child stuff
base.Initialize();
}
}
Sửa
Như đã đề cập trong bình luận của Terrence của bên dưới, đây là một cách tiếp cận rủi ro vì Initialize()
sẽ được thực hiện trước khi Child
của constructor được thực thi. Nếu có bất kỳ trường nào được khởi tạo trong hàm tạo của Child
, chúng sẽ không sẵn sàng nếu chúng được sử dụng bởi Initialize()
. Điều này có thể gây ra các lỗi gây nhầm lẫn.
Một giải pháp đơn giản là từ bỏ yêu cầu của Phụ huynh Initialize()
và thay vào đó có các lớp con gọi Initialize()
. Như những người khác đã đề xuất, một tùy chọn khác sẽ là sử dụng mẫu nhà máy trừu tượng.
Đây là một giải pháp đơn giản có sử dụng một phương pháp nhà máy tĩnh:
class Program
{
static void Main()
{
Child.Create(() => new Child(5));
Console.ReadKey();
}
}
public abstract class Parent
{
protected virtual void Initialize()
{
Console.Write(" is the number.");
}
public static TChild Create<TChild>(Func<TChild> childGetter)
where TChild : Parent
{
var child = childGetter();
child.Initialize();
return child;
}
}
public class Child : Parent
{
private int _number;
public Child(int number)
{
_number = number;
}
protected override void Initialize()
{
Console.Write(_number.ToString());
base.Initialize();
}
}
Điều này vi phạm các khuyến nghị chống gọi điện thoại ảo Phương pháp này có thể dẫn đến khó theo dõi lỗi. Xem: http://blogs.msdn.com/b/scottwil/archive/2005/01/14/353177.aspx và http : //stackoverflow.com/questions/308061/virtual ization-in-super-class-constructor – Terrence
@Terrence, cảm ơn nhận xét của bạn. Đã cập nhật câu trả lời của tôi. – devuxer
Không có gì được xây dựng vào ngôn ngữ C# cho phép bạn làm điều này là. Tuy nhiên, bằng cách sử dụng một mô hình sáng tạo có thể hỗ trợ nó. Ví dụ: mẫu Abstract Factory có thể hữu ích ở đây. Nhà máy cơ sở sẽ đảm bảo rằng một phương thức được gọi trên lớp cơ sở mới được tạo ra khi nó được khởi tạo như là kiểu con cụ thể.
Bạn có biết nếu Castle Windsor có thứ như thế không? –
Đây thực sự là tên miền của một công cụ AOP như PostSharp (mà bây giờ bạn đã nhắc nhở tôi nên được đưa vào câu trả lời của tôi), nhưng có thể có Windsor làm điều đó. Chưa bao giờ thử. – RationalGeek
- 1. C# Làm thế nào để thực thi mã sau khi xây dựng đối tượng (postconstruction)
- 2. Thực thi mã jQuery sau khi tất cả các quy tắc CSS đã được áp dụng
- 3. SPARQL: Nhận tất cả các thực thể của các lớp con của một lớp nhất định
- 4. PHP: Quấn tất cả các chức năng của một lớp trong một lớp con
- 5. Thực thi toString() trong các lớp con
- 6. Làm thế nào để thực hiện một đoạn mã chỉ sau khi tất cả các chủ đề được thực hiện
- 7. Làm cách nào để chạy một phương thức trước tất cả các bài kiểm tra trong tất cả các lớp?
- 8. Là một nhà xây dựng công cộng trong một lớp trừu tượng một mã số?
- 9. Làm cách nào để tạo một lớp chung cho tất cả các loại số?
- 10. Làm cách nào để thực thi một hàm JavaScript sau khi tải trang được hoàn tất?
- 11. Làm cách nào để bỏ qua một siêu lớp?
- 12. Làm thế nào để thực hiện một số mã sau khi một segue được thực hiện?
- 13. Chạy một phương pháp sau các nhà xây dựng của bất kỳ lớp được thừa kế
- 14. Ruby: Thực thi mã cho mỗi lớp con
- 15. cách lấy tất cả các lớp con của một lớp trong php
- 16. Sử dụng Reflection để xây dựng một Class (để xây dựng một lớp FileHelper động)
- 17. Làm cách nào để phân lớp lệnh xây dựng?
- 18. Tránh xác định tất cả các đối số trong một lớp con
- 19. Siêu kết nối XJC và siêu lớp chỉ dành cho tất cả các lớp?
- 20. đúng cách để kết hợp siêu lớp vào một thực thi Object Objects.hashcode()??
- 21. Cách chạy mã sau khi tất cả các sự kiện khác đã được xử lý
- 22. Phân lớp - Các đối số từ siêu lớp
- 23. Xem tất cả các lớp học siêu trong Java
- 24. C++ - xây dựng một đối tượng bên trong một lớp
- 25. Làm thế nào để áp dụng một phaselistener JSF2 sau khi xem được xây dựng?
- 26. Maven - Bỏ qua các lớp thi xây dựng
- 27. Làm cách nào để ghi đè đúng một phương thức lớp trong một Objective-C trong một lớp con?
- 28. Các trình xây dựng lớp trừu tượng không được gọi ngầm khi một lớp dẫn xuất được khởi tạo?
- 29. Làm thế nào để tạo một trường ánh xạ được kế thừa từ một siêu lớp siêu trong JPA?
- 30. Chức năng thực thi sau khi tất cả các yêu cầu ajax .load() được hoàn thành
Bạn có ví dụ sử dụng cụ thể không? –