有没有办法在所有构造函数运行后立即自动调用特定方法?

我希望能够在构造派生对象时自动调用特定方法,但是我想不出怎么做。 以下代码说明。 另一个答案推荐OnLoad,但我在Mac上为Unity做这个,OnLoad似乎不支持我的平台。 有什么建议?

public class Parent { public Parent () { // A. Stuff to do before child constructor code runs DoThisAutomaticallyAfterConstruction(); } public void DoThisAutomaticallyAfterConstruction() { // C. In this example, this will run after A, before B. I want it to run ABC } } public class Child : Parent { public Child () : base() { // B. Stuff to do here after parent constructor code runs } } 

不幸的是,没有内置的方法可以做你想要的(这是一个经常被要求的function)。

一种解决方法是实现工厂模式,您不通过直接调用构造函数来创建对象,而是实现静态方法来为您创建它们。 例如:

 public class MyClass { public MyClass() { // Don't call virtual methods here! } public virtual void Initialize() { // Do stuff -- but may be overridden by derived classes! } } 

然后加:

 public static MyClass Create() { var result = new MyClass(); // Safe to call a virtual method here result.Initialize(); // Now you can do any other post-constructor stuff return result; } 

而不是做

 var test = new MyClass(); 

你可以做

 var test = MyClass.Create(); 

这听起来像是工厂的一个很好的候选人。 使所有构造函数成为私有或受保护的,要求代码的使用者在需要对象实例时调用工厂方法。 在工厂方法中,使用new运算符创建对象,然后在返回对象之前调用DoThisAutomaticallyAfterConstruction()

编辑

工厂可能是静态方法,或者您可能有工厂对象。 例如,参见http://en.wikipedia.org/wiki/Abstract_factory_pattern上的抽象工厂模式的维基百科,以及http://msdn.microsoft.com/en-us/上的ADO.NET DbProviderFactories的文档。 library / wda6c36e.aspx用于实际实现。

根据您的示例,您正在完成ACB ,您想要完成ABC

为了在子构造函数之后运行代码,你需要在B(子构造函数)之后调用你不能在A(父构造函数)调用代码然后你不会完成ABC。

在子类构造函数的末尾移动DoThisAutomaticallyAfterConstruction()

真的是一个奇怪的问题。

虽然@Jeremy Todd(已接受)的答案有效并且是一个被广泛接受的问题解决方案,但它有一个缺点:不是非常IoC和序列化友好,因为你的类无法使用new正确构造。 让我介绍使用一些C#function的一般解决方案。 请注意,此解决方案不需要您在构造对象后使用工厂模式或调用任何内容,并且它适用于任何类,只需使用单个方法实现接口。 首先,我们声明一个我们的类必须实现的接口:

 public interface IInitialize { void OnInitialize(); } 

接下来,我们为此接口添加一个静态扩展类,并添加Initialize方法:

 public static class InitializeExtensions { public static void Initialize(this T obj) where T: IInitialize { if (obj.GetType() == typeof(T)) obj.OnInitialize(); } } 

现在,如果我们需要一个类及其所有后代在对象完全构造之后立即调用初始化器,我们需要做的就是实现IInitialize并在构造函数中追加一行:

 public class Parent : IInitialize { public virtual void OnInitialize() { Console.WriteLine("Parent"); } public Parent() { this.Initialize(); } } public class Child : Parent { public Child() { this.Initialize(); } public override void OnInitialize() { Console.WriteLine("Child"); } } public class GrandChild : Child { public GrandChild() { this.Initialize(); } public override void OnInitialize() { Console.WriteLine("GrandChild"); } } 

诀窍是,当派生类调用扩展方法Initialize ,这将抑制未从实际类中进行的任何调用。