Call Constructor Base after Code Execution - c#

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?

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

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

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

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.

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

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.

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

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

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.

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

Related

How to hide methods outside the class

I'm trying to do something, but I don't know if it's possible
I have these classes:
public Class1
{
private Class2 class2;
public Class1
{
this.class2 = new Class2();
}
public Class2 Do()
{
return class2.Build();
}
}
internal Class2
{
public internal Class2 Build()
{
return this;
}
public void Fill()
{
}
}
var class1 = new Class1();
class1.Do().Fill();
I want it when the user types class1.Do (). only the Fill () method is accessible. How can I do this?
The goal would be to prevent class1.Do().Build();
There are quite a few errors in the code posted as mentioned in a comment. For the sake of an example answer, I made all of the troublesome places public. So while this will compile, take it with a grain of salt and adjust your accessibility modifiers appropriately.
Firstly, I created a new interface to only expose Fill, and not Build:
public interface IClass2Helper
{
void Fill();
}
I made a couple of small changes to Class1 and Class2 so that they become compilable, to implement the interface in Class2 and return the interface in the Do() method in Class1:
public class Class1
{
private Class2 class2;
public Class1()
{
this.class2 = new Class2();
}
public IClass2Helper Do()
{
return class2.Build();
}
}
public class Class2 : IClass2Helper
{
public Class2 Build()
{
return this;
}
public void Fill() { }
}
And added a simple test class/method to verify:
class TestProgram
{
static void Main()
{
var class1 = new Class1();
class1.Do().Fill(); //This line is OK
//The below line will have an error since the interface doesn't expose a Build method
class1.Do().Build();
}
}
A fiddle to the code:
https://dotnetfiddle.net/5EPPfO

C# class constructors creating infinite loop

So lets say I have two classes. Class A and Class B like this:
Class A
{
B classB;
public A
{
classB = new B();
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B
{
classA = new A();
}
public void funcIHaveToUseInClassA()
{
}
}
As you can see both classes contain functions that need to be used in the other class. Class A has a function that class B has to use and the other way around. No I can't just put the functions in the other class because they heavily rely on the class they are currently in. So how would I go about doing this? With my method I create an infinite loop and get a stack overflow exception. I hope someone can help me out, thanks in advance.
EDIT:
People are asking me why I need these 2 classes to rely on each other so here it is: Class A manages everything that has to do with a WebBrowser control and class B Manages everything that has to do with a certain page in my program. Class A is being used by multiple pages, which is the reason it needs to be a seperate class. Class A sometimes needs to push info to class B. Class B sometimes needs info from the WebBrowser control class A is managing and that is why it calls a function.
Make classB and classA into public properties and initialize them from another class instead of constructor.
class A
{
public B classB { get; set; }
public void funcIHaveToUseInClassB()
{
}
public void anotherF()
{
classB.funcIHaveToUseInClassA();
}
}
class B
{
public A classA { get; set; }
public void funcIHaveToUseInClassA()
{
}
public void anotherF()
{
classA.funcIHaveToUseInClassB();
}
}
static void main()
{
// entry point
var a = new A();
var b = new B();
a.classB = b;
b.classA = a;
// do what ever you want with a and b
}
You need to pass an instance of one of your classes to the constructor of the other class.
Try this:
Class A
{
B classB;
public A()
{
classB = new B(this);
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B(A arg)
{
classA = arg;
}
public void funcIHaveToUseInClassA()
{
}
}
Update
Or just pass in the instance as a parameter to the methods like in Matt Jacobsen's answer.
Create a private and public accessor, and instantiate the property only when the private object is null, like so:
class A
{
private B _b;
public B b {
get {
if (_b == null) _b = new B();
return _b;
}
}
// Constructor can now be empty
public A()
{
}
}
Pass your reference from B/A in to A/B each time you need to use it. You don't need the constructors.
Class A
{
public void funcIHaveToUseFromClassB(B classB)
{
}
}
Class B
{
public void funcIHaveToUseFromClassA(A classA)
{
}
}

Get current class at runtime in a static method?

How can I get the type (not a name string, but a type itself) of the current class, in a static method of an abstract class?
using System.Reflection; // I'll need it, right?
public abstract class AbstractClass {
private static void Method() {
// I want to get CurrentClass type here
}
}
public class CurrentClass : AbstractClass {
public void DoStuff() {
Method(); // Here I'm calling it
}
}
This question is very similar to this one:
How to get the current class name at runtime?
However, I want to get this information from inside the static method.
public abstract class AbstractClass
{
protected static void Method<T>() where T : AbstractClass
{
Type t = typeof (T);
}
}
public class CurrentClass : AbstractClass
{
public void DoStuff()
{
Method<CurrentClass>(); // Here I'm calling it
}
}
You can gain access to the derived type from the static method simply by passing the type as a generic type argument to the base class.
I think you will have to either pass it in like the other suggestion or create a stack frame, I believe if you put an entire stack trace together though it can be expensive.
See http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx
if you are calling this static method only from derived classes you can use 'System.Diagnostics.StackTrace' like
abstract class A
{
public abstract string F();
protected static string S()
{
var st = new StackTrace();
// this is what you are asking for
var callingType = st.GetFrame(1).GetMethod().DeclaringType;
return callingType.Name;
}
}
class B : A
{
public override string F()
{
return S(); // returns "B"
}
}
class C : A
{
public override string F()
{
return S(); // returns "C"
}
}
The method can't be static if you're going to call it without passing in a type. You can do this:
public abstract class AbstractClass {
protected void Method() {
var t = GetType(); // it's CurrentClass
}
}
If you also need it to be accessible from a static context, you can add an overload, even a generic overload, e.g.:
public abstract class AbstractClass {
protected static void Method<T>() {
Method(typeof(T));
}
protected static void Method(Type t) {
// put your logic here
}
protected void Method() {
Method(GetType());
}
}

Calling a base class' method

In c++ I would do
class A
{
public:
virtual void stuff()
{
//something
}
};
class B : public A
public:
virtual void stuff()
{
//something2
A::stuff() //something
}
};
How would I do this in C#?
I've tried
public void stuff()
{
//something2
A.stuff(); //something
}
but that doesn't work
base is the keyword for referencing your superclass in C#. Use:
base.stuff();
Use base. Like base.stuff();
Just to add to the answer above, base.stuff() works, unless it's the constructor you're trying to call in which case it is called as:
class A
{
public:
public A(){}
};
class B : A
{
public B() : base()
{
}
};

Constructor initializer does not allow me to use 'this'

Compiler Error
Keyword 'this' is not available in the current context
delegate void CallBack(int i);
class A
{
public A(CallBack cb) { }
}
class B : A
{
public B() : base(new CallBack(this.f)){}
private void f(int i) { }
}
Why is this error ?
As a solution I thought of providing a parameterless protected ctor in A() and have
class B : A
{
public B() : base() // inherit the new A() ctor
{
base.cb = new CallBack(this.f); //this is allowed here
}
//...
}
It's because "this" hasn't been created until the base class constructor has run.
In your 2nd example the base constructor has finished, and now "this" has meaning.
In the first example the B instance is not initialized yet. In the second, it is.
Since the object is not yet (fully) constructed, that is the base constructor was not yet run, this is not available there.
You should use a abstract/virtual method.
abstract class A {
A() {
this.Initialize();
}
abstract void Initialize() { }
}
class B : A {
string Text;
B() { }
override void Initialize() {
this.Text = "Hello world";
}
}

Categories

Resources