执行代码后调用构造函数库

Gus*_*014 17 c# constructor

假设我们有A类和B类.BlassB扩展了A类.(ClassB:ClassA)

现在让我们说每当我实例化ClassB时,我想运行一些随机代码,然后调用"base"来达到ClassA构造函数.

喜欢:

class ClassA
{
    public ClassA()
    {
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    public ClassB() //: base() 
    {
        // Using :base() as commented above, I would execute ClassA ctor before                                                         //          Console.WriteLine as it is below this line... 
        Console.WriteLine("Before new");
        //base() //Calls ClassA constructor using inheritance
        //Run some more Codes here...
    }
}
Run Code Online (Sandbox Code Playgroud)

在编程语言我平时一起工作,我能做到这一点,通过简单地调用super()之后Console.WriteLine(); 但我不能在C#中做到这一点.有没有其他语法或其他方法可以做到这一点?

Jon*_*eet 26

使用实例变量初始化器有一种hacky方式:

using System;

class ClassA
{
    public ClassA()
    {
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    private readonly int ignoreMe = BeforeBaseConstructorCall();

    public ClassB()
    {
    }

    private static int BeforeBaseConstructorCall()
    {
        Console.WriteLine("Before new");
        return 0; // We really don't care
    }
}

class Test
{
    static void Main()
    {
        new ClassB();
    }    
}
Run Code Online (Sandbox Code Playgroud)

做的哈克的方式是重新思考如何构建一个ClassB开始.不是让客户端直接调用构造函数,而是为它们提供一个静态方法来调用:

public static ClassB CreateInstance()
{
    Console.WriteLine("Before initialization stuff");
    return new ClassB();
}
Run Code Online (Sandbox Code Playgroud)


Kry*_*ypt 6

其实你可以:

class Foo
{
    public Foo(string s)
    {
        Console.WriteLine("inside foo");
        Console.WriteLine("foo" + s);
    }
}

class Bar : Foo
{
    public Bar(string s) : base(((Func<string>)(delegate ()
    {
        Console.WriteLine("before foo");
        return "bar" + s;
    }))())
    {
        Console.WriteLine("inside bar");
    }
}

class Program
{
    static void Main(string[] args)
    {
        new Bar("baz");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

before foo
inside foo
foobarbaz
inside bar
Run Code Online (Sandbox Code Playgroud)

但如果可能的话,我宁愿不使用这个技巧。


Spe*_*evy 5

另一个黑客,如果你可以逃脱调用静态方法.

public class ClassA
{
    public ClassA()
    {
        Debug.WriteLine("Call A Constructor");
    }
}

public class ClassB:ClassA
{
    public ClassB():this(aMethod())
    {
    }

    private ClassB(object empty):base()
    {
        Debug.WriteLine("Class B Second Constructor");
    }

    private static object aMethod()
    {
        Debug.WriteLine("Run me First");
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

另一个优雅的解决方案是完全重新思考对象的构造方式.在基类的构造construct函数中,您可以通过以下方式调用自己的函数,并省略依赖的将来构造函数:

public class ClassA
{
    public ClassA()
    {
        Construct();
    }

    public virtual void Construct()
    {
        Console.WriteLine("3");
    }
}

public class ClassB : ClassA
{
    public override void Construct()
    {
        Console.WriteLine("2");
        base.Construct();
    }
}

public class ClassC : ClassB
{
    public override void Construct()
    {
        Console.WriteLine("1");
        base.Construct();
    }
}
Run Code Online (Sandbox Code Playgroud)