Gus2014
Gus2014

Reputation: 363

Call Constructor Base after Code Execution

Let say we have Class A and Class B. ClassB extends Class A. (ClassB : ClassA)

Now let's say that whenever I instantiate ClassB, I'd like to Run some Random code and only then call "base" to reach ClassA constructor.

Like:

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...
    }
}

In the programming language I usually work with, I can do that, by simply calling super() after Console.WriteLine(); But I cant make it in C#. Is there any other syntax or other way to do that?

Upvotes: 26

Views: 21264

Answers (10)

statler
statler

Reputation: 1381

I am surprised noone has suggested using an abstract method - though it does rely on the base being implemented as an abstract class which wont work for all cases (although you could simply fork the inheritance and stack the non-abstract on top if yu have to). This has the advantage of ensuring the integrity of your code without resorting to hackiness. Because we are using abstract, it is not possible to instantiate the derived class without declaring initCode.

using System;

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

class ClassB : ClassA
{
    public ClassB()
    {
    }
    
    internal override initCode()
    {
        Console.WriteLine("Before new");
        return 0; // We really don't care
    }
}

//If you need to effectively get the non-abstract of ClassA
class ClassC : ClassA
{
    public ClassB()
    {
    }
    
    internal override initCode()
    {
    }
}

Upvotes: 1

Krypt
Krypt

Reputation: 511

Actually, you can:

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");
    }
}

Output:

before foo
inside foo
foobarbaz
inside bar

But I will prefer to not use this trick if it is possible.

Upvotes: 8

Euthanatos
Euthanatos

Reputation: 1

I had the same problem. I found this solution to be the best if you don't have access to the base class.

public class BaseClass
{
    public BaseClass(string someValue)
    {
        Console.WriteLine(someValue);
    }
}

public class MyClass : BaseClass
{
    private MyClass(string someValue)
        : base(someValue)
    {
    }

    public static MyClass GetNewInstance(string someValue, bool overrideValue = false)
    {
        if (overrideValue)
        {
            someValue = "42";
        }
        return new MyClass(someValue);
    }
}

Upvotes: 0

PietjePuk
PietjePuk

Reputation: 87

Another elegant solution would be to completely rethink how your objects are constructed. In the constructor of your base class you can call your own construct function, and you omit dependent future constructors, in the following way:

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();
    }
}

Upvotes: 7

Ryan Mann
Ryan Mann

Reputation: 5357

Recently I ran into a scenario where I needed to calculate some logic before passing the result into base.

I could just do something like

public SomeConstructor: base(FlagValue == FlagValues.One || FlagValues.Two ? "OptionA" : "OptionB")
{

}

But I find that to be ugly, and can get really long horizontally. So I opted instead to use Func Anonymous methods.

E.g. imagine you have a base class,

public class SomeBaseClass
{
  public SomeBaseClass(Func<string> GetSqlQueryText){
    string sqlQueryText = GetSqlQueryText();
    //Initialize(sqlQueryText);
  }
}

Now you inherit from that and want to do some logic to determine the sql query text,

public class SomeSqlObject : SomeBaseClass
{
  public SomeSqlObject(ArchiveTypeValues archiveType)
        : base(delegate()
        {
            switch (archiveType)
            {
                case ArchiveTypeValues.CurrentIssues:
                case ArchiveTypeValues.Archived:
                    return Queries.ProductQueries.ProductQueryActive;
                case ArchiveTypeValues.AllIssues:
                    return     string.Format(Queries.ProductQueries.ProductQueryActiveOther, (int)archiveType);
                default:
                    throw new InvalidOperationException("Unknown archiveType");
            };
        })
    {
        //Derived Constructor code here!
    }

}

In this way you can execute code before Base is called and (in my opinion) it's not really hacky.

Upvotes: 0

Spevy
Spevy

Reputation: 1325

Another hack if you can get away with calling a static method.

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;
    }
}

Upvotes: 8

Jon Skeet
Jon Skeet

Reputation: 1502096

There's a hacky way of doing it using an instance variable initializer:

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();
    }    
}

The less hacky way of doing it is to rethink how you construct a ClassB to start with. Instead of having clients call the constructor directly, provide a static method for them to call:

public static ClassB CreateInstance()
{
    Console.WriteLine("Before initialization stuff");
    return new ClassB();
}

Upvotes: 33

Md Kamruzzaman Sarker
Md Kamruzzaman Sarker

Reputation: 2407

You can not call base constructor. But a different thing is that when you declare an object of derived class both constructor derived and base is called.

    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...
    }
}
void main(string[] args)
    {
      ClassB b = new ClassB();

    }

Upvotes: 0

Oleksi
Oleksi

Reputation: 13097

You can't do that with C#. Your best bet is to extract that code into it's own method in the parent and then call that from the child when you're ready.

Upvotes: 1

detale
detale

Reputation: 12920

C# doesn't allow calling base constructors inside constructor bodies, different from Java.

Upvotes: 1

Related Questions