Related
I'm getting a warning from ReSharper about a call to a virtual member from my objects constructor.
Why would this be something not to do?
When an object written in C# is constructed, what happens is that the initializers run in order from the most derived class to the base class, and then constructors run in order from the base class to the most derived class (see Eric Lippert's blog for details as to why this is).
Also in .NET objects do not change type as they are constructed, but start out as the most derived type, with the method table being for the most derived type. This means that virtual method calls always run on the most derived type.
When you combine these two facts you are left with the problem that if you make a virtual method call in a constructor, and it is not the most derived type in its inheritance hierarchy, that it will be called on a class whose constructor has not been run, and therefore may not be in a suitable state to have that method called.
This problem is, of course, mitigated if you mark your class as sealed to ensure that it is the most derived type in the inheritance hierarchy - in which case it is perfectly safe to call the virtual method.
In order to answer your question, consider this question: what will the below code print out when the Child object is instantiated?
class Parent
{
public Parent()
{
DoSomething();
}
protected virtual void DoSomething()
{
}
}
class Child : Parent
{
private string foo;
public Child()
{
foo = "HELLO";
}
protected override void DoSomething()
{
Console.WriteLine(foo.ToLower()); //NullReferenceException!?!
}
}
The answer is that in fact a NullReferenceException will be thrown, because foo is null. An object's base constructor is called before its own constructor. By having a virtual call in an object's constructor you are introducing the possibility that inheriting objects will execute code before they have been fully initialized.
The rules of C# are very different from that of Java and C++.
When you are in the constructor for some object in C#, that object exists in a fully initialized (just not "constructed") form, as its fully derived type.
namespace Demo
{
class A
{
public A()
{
System.Console.WriteLine("This is a {0},", this.GetType());
}
}
class B : A
{
}
// . . .
B b = new B(); // Output: "This is a Demo.B"
}
This means that if you call a virtual function from the constructor of A, it will resolve to any override in B, if one is provided.
Even if you intentionally set up A and B like this, fully understanding the behavior of the system, you could be in for a shock later. Say you called virtual functions in B's constructor, "knowing" they would be handled by B or A as appropriate. Then time passes, and someone else decides they need to define C, and override some of the virtual functions there. All of a sudden B's constructor ends up calling code in C, which could lead to quite surprising behavior.
It is probably a good idea to avoid virtual functions in constructors anyway, since the rules are so different between C#, C++, and Java. Your programmers may not know what to expect!
Reasons of the warning are already described, but how would you fix the warning? You have to seal either class or virtual member.
class B
{
protected virtual void Foo() { }
}
class A : B
{
public A()
{
Foo(); // warning here
}
}
You can seal class A:
sealed class A : B
{
public A()
{
Foo(); // no warning
}
}
Or you can seal method Foo:
class A : B
{
public A()
{
Foo(); // no warning
}
protected sealed override void Foo()
{
base.Foo();
}
}
In C#, a base class' constructor runs before the derived class' constructor, so any instance fields that a derived class might use in the possibly-overridden virtual member are not initialized yet.
Do note that this is just a warning to make you pay attention and make sure it's all-right. There are actual use-cases for this scenario, you just have to document the behavior of the virtual member that it can not use any instance fields declared in a derived class below where the constructor calling it is.
There are well-written answers above for why you wouldn't want to do that. Here's a counter-example where perhaps you would want to do that (translated into C# from Practical Object-Oriented Design in Ruby by Sandi Metz, p. 126).
Note that GetDependency() isn't touching any instance variables. It would be static if static methods could be virtual.
(To be fair, there are probably smarter ways of doing this via dependency injection containers or object initializers...)
public class MyClass
{
private IDependency _myDependency;
public MyClass(IDependency someValue = null)
{
_myDependency = someValue ?? GetDependency();
}
// If this were static, it could not be overridden
// as static methods cannot be virtual in C#.
protected virtual IDependency GetDependency()
{
return new SomeDependency();
}
}
public class MySubClass : MyClass
{
protected override IDependency GetDependency()
{
return new SomeOtherDependency();
}
}
public interface IDependency { }
public class SomeDependency : IDependency { }
public class SomeOtherDependency : IDependency { }
Yes, it's generally bad to call virtual method in the constructor.
At this point, the objet may not be fully constructed yet, and the invariants expected by methods may not hold yet.
Because until the constructor has completed executing, the object is not fully instantiated. Any members referenced by the virtual function may not be initialised. In C++, when you are in a constructor, this only refers to the static type of the constructor you are in, and not the actual dynamic type of the object that is being created. This means that the virtual function call might not even go where you expect it to.
Your constructor may (later, in an extension of your software) be called from the constructor of a subclass that overrides the virtual method. Now not the subclass's implementation of the function, but the implementation of the base class will be called. So it doesn't really make sense to call a virtual function here.
However, if your design satisfies the Liskov Substitution principle, no harm will be done. Probably that's why it's tolerated - a warning, not an error.
One important aspect of this question which other answers have not yet addressed is that it is safe for a base-class to call virtual members from within its constructor if that is what the derived classes are expecting it to do. In such cases, the designer of the derived class is responsible for ensuring that any methods which are run before construction is complete will behave as sensibly as they can under the circumstances. For example, in C++/CLI, constructors are wrapped in code which will call Dispose on the partially-constructed object if construction fails. Calling Dispose in such cases is often necessary to prevent resource leaks, but Dispose methods must be prepared for the possibility that the object upon which they are run may not have been fully constructed.
One important missing bit is, what is the correct way to resolve this issue?
As Greg explained, the root problem here is that a base class constructor would invoke the virtual member before the derived class has been constructed.
The following code, taken from MSDN's constructor design guidelines, demonstrates this issue.
public class BadBaseClass
{
protected string state;
public BadBaseClass()
{
this.state = "BadBaseClass";
this.DisplayState();
}
public virtual void DisplayState()
{
}
}
public class DerivedFromBad : BadBaseClass
{
public DerivedFromBad()
{
this.state = "DerivedFromBad";
}
public override void DisplayState()
{
Console.WriteLine(this.state);
}
}
When a new instance of DerivedFromBad is created, the base class constructor calls to DisplayState and shows BadBaseClass because the field has not yet been update by the derived constructor.
public class Tester
{
public static void Main()
{
var bad = new DerivedFromBad();
}
}
An improved implementation removes the virtual method from the base class constructor, and uses an Initialize method. Creating a new instance of DerivedFromBetter displays the expected "DerivedFromBetter"
public class BetterBaseClass
{
protected string state;
public BetterBaseClass()
{
this.state = "BetterBaseClass";
this.Initialize();
}
public void Initialize()
{
this.DisplayState();
}
public virtual void DisplayState()
{
}
}
public class DerivedFromBetter : BetterBaseClass
{
public DerivedFromBetter()
{
this.state = "DerivedFromBetter";
}
public override void DisplayState()
{
Console.WriteLine(this.state);
}
}
The warning is a reminder that virtual members are likely to be overridden on derived class. In that case whatever the parent class did to a virtual member will be undone or changed by overriding child class. Look at the small example blow for clarity
The parent class below attempts to set value to a virtual member on its constructor. And this will trigger Re-sharper warning, let see on code:
public class Parent
{
public virtual object Obj{get;set;}
public Parent()
{
// Re-sharper warning: this is open to change from
// inheriting class overriding virtual member
this.Obj = new Object();
}
}
The child class here overrides the parent property. If this property was not marked virtual the compiler would warn that the property hides property on the parent class and suggest that you add 'new' keyword if it is intentional.
public class Child: Parent
{
public Child():base()
{
this.Obj = "Something";
}
public override object Obj{get;set;}
}
Finally the impact on use, the output of the example below abandons the initial value set by parent class constructor.
And this is what Re-sharper attempts to to warn you, values set on the Parent class constructor are open to be overwritten by the child class constructor which is called right after the parent class constructor.
public class Program
{
public static void Main()
{
var child = new Child();
// anything that is done on parent virtual member is destroyed
Console.WriteLine(child.Obj);
// Output: "Something"
}
}
Beware of blindly following Resharper's advice and making the class sealed!
If it's a model in EF Code First it will remove the virtual keyword and that would disable lazy loading of it's relationships.
public **virtual** User User{ get; set; }
There's a difference between C++ and C# in this specific case.
In C++ the object is not initialized and therefore it is unsafe to call a virutal function inside a constructor.
In C# when a class object is created all its members are zero initialized. It is possible to call a virtual function in the constructor but if you'll might access members that are still zero. If you don't need to access members it is quite safe to call a virtual function in C#.
Just to add my thoughts. If you always initialize the private field when define it, this problem should be avoid. At least below code works like a charm:
class Parent
{
public Parent()
{
DoSomething();
}
protected virtual void DoSomething()
{
}
}
class Child : Parent
{
private string foo = "HELLO";
public Child() { /*Originally foo initialized here. Removed.*/ }
protected override void DoSomething()
{
Console.WriteLine(foo.ToLower());
}
}
I think that ignoring the warning might be legitimate if you want to give the child class the ability to set or override a property that the parent constructor will use right away:
internal class Parent
{
public Parent()
{
Console.WriteLine("Parent ctor");
Console.WriteLine(Something);
}
protected virtual string Something { get; } = "Parent";
}
internal class Child : Parent
{
public Child()
{
Console.WriteLine("Child ctor");
Console.WriteLine(Something);
}
protected override string Something { get; } = "Child";
}
The risk here would be for the child class to set the property from its constructor in which case the change in the value would occur after the base class constructor has been called.
My use case is that I want the child class to provide a specific value or a utility class such as a converter and I don't want to have to call an initialization method on the base.
The output of the above when instantiating the child class is:
Parent ctor
Child
Child ctor
Child
I would just add an Initialize() method to the base class and then call that from derived constructors. That method will call any virtual/abstract methods/properties AFTER all of the constructors have been executed :)
Another interesting thing I found is that the ReSharper error can be 'satisfied' by doing something like below which is dumb to me. However, as mentioned by many earlier, it still is not a good idea to call virtual properties/methods in constructor.
public class ConfigManager
{
public virtual int MyPropOne { get; private set; }
public virtual string MyPropTwo { get; private set; }
public ConfigManager()
{
Setup();
}
private void Setup()
{
MyPropOne = 1;
MyPropTwo = "test";
}
}
Generally, Constructor is the very first thing to be executed in class when it's instantiated.
But in following case, A member methods of the class are executed first & then the constructor.
Why is it so?
A Code Scenario :
namespace AbsPractice
{
class Program
{
static void Main(string[] args)
{
SavingsCustomer sc = new SavingsCustomer();
CorporateCustomer cc = new CorporateCustomer();
}
}
public abstract class Customer
{
protected Customer()
{
Console.WriteLine("Constructor of Abstract Customer");
Print();
}
protected abstract void Print();
}
public class SavingsCustomer : Customer
{
public SavingsCustomer()
{
Console.WriteLine("Constructor of SavingsCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of SavingsCustomer");
}
}
public class CorporateCustomer : Customer
{
public CorporateCustomer()
{
Console.WriteLine("Constructor of CorporateCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of CorporateCustomer");
}
}
}
That's because when you call SavingsCustomer ctor, first of all its base class ctor is called; in Customer ctor you call Print that's an overridden method.
So basicly before SavingsCustomer ctor instructions are executed, Customer ctor must be completely called.
Note that when you call Print from Customer, SavingsCustomer.Print() is executed.
This is the expected behaviour; if you want your classes to behave differently, you must change their logic. Maybe you shouldn't call an abstract method from base constructor, just to avoid what you're seeing now...
You should never, never do this unless you have a very good reason.
Calling a virtual method from a constructor is a disaster waiting to happen.
In C# object construction follows the class hierarchy order; that is, when a constructor is invoked, the most base class constructor is called first, then the immediately derived class constructor, then the next, etc. etc. (if I'm not mistaken, in C++ it's the other way around which can lead to even more confusion).
So when you call a virtual method from a constructor what really happens is that the virtual method, if overridden (which in your case is a guarantee), will be executed before the implementing class constructor is invoked. This means that the method could be executed before the object's state has been correctly initialized (normally via the constructor; if the method does not depend on any object state then this pattern is not an issue although I'd still not recommend it).
If it is absolutely necessary to use this pattern, good practices recommend implementing an Initialize() method and do any virtual calls form there. Enforcing consumers to call Initialize before using the object is a trivial task and you guarantee that the object's state will always be valid when the virtual call is made.
Tricky question.When You Create an object like this
SavingsCustomer sc = new SavingsCustomer();
It invokes constructor of Customer[base of class SavingsCustomer],means Customer()
- which inturn invoke Print() from class SavingsCustomer as it is abstract in Customer Class.
Eventhough it is a member function of SavingsCustomer it can be called from Customer class before calling constructor of SavingsCustomer Becuase Print() is declared as abstract method so it is shared by these two classes.
Same happens in the following declaration
CorporateCustomer cc = new CorporateCustomer();
Print() from CorporateCustomer class is called since SavingsCustomer.Print() is overrided
The question title seems a little bit odd doesn't it. Anyway. So I have one base class which has some private fields, protected properties and a single constructor that takes one argument and I have several sub classes of that base class. whenever any of those subclass methods are called the sub classes are required to be instantiated and after the method is done executed the object is destroyed so if the method will be called again new instance of the class should be made. (Its a WCF service) Now, the thing I want to do is the following. whenever the certain sub class constructor is called I call the base class constructor explicitly with some certain parameter (different for every sub class, Note: no sub class methods are the same), When the base class constructor is called I want to check something according to that argument and if it passes the check then I want to allow the execution of sub class method. In any other case I want it NOT to run the sub class method. So I want something like this. when the method is called the sub class has to be constructed and for that, base class has to be constructed as well and if the check fails in the base class' constructor I want to prevent that method from running. I can just have a bool property and set it in base class' constructor and check it on every method call. but I want to make something more general. May be the way that I'm suggesting Is not right either. So you understand what I want I guess. Any suggestion would be appriciated. thanks in advance
class BaseClass
{
private bool _isValid;
private SomeService someService;
public BaseClass(SomeEnum value)
{
someService = new SomeService();
if (someService.Validate(value))
{
_isValid = true;
}
}
protected internal bool IsValid { get { return _isValid; } }
}
class SubClass : BaseClass
{
// object declaration
public SubClass () : base(SomeEnum.SomeValue)
{
// constructing some objects here
}
public Response Operation('parametereGoHere')
{
if (IsValid)
{
// perform operation. construct Response object and return it
}
}
// other methods omitted.
}
So whenever the Operation() method is called SubClass has to be constructed which causes the BaseClass to be constructed and the base class sets the value of _isValid which is then use to check for validity, but I wanted to make something more general. lets that instead of just setting the value of _isValid to true just do nothing or set some other properties and if the Valiate() failed just stop the execution and don't to anything at all. In this case the calling routing wouldn't be able to call Operation() if we somehow managed to stop the construction of class. If it's not possible I'm perfectly happy with the solution I have right now. But if it is I will be glad to see that. Note: In every sub class, methods are different and I have to check IsValid to allow the execution of method.
You should be able to use the out parameter to get the constructor to return a value.
Very hard to follow what you want, but it sounds like you want a case where the base constructor doesn't do anything sometimes. Then simply make a base constructor that doesn't do anything, and call it (with the : base() call). Use a dummy argument if necessary.
class A {
public A() { a= 1; }
public A(double dummy); { }
}
class B
public B() : base() { // calls the base constructor that does something
}
public B(int) : base(1.0) {// class the base construct that does nothing
}
}
Is it possible to call the current classes methods in a class inheritance?
Lets say we have a class A and a Class B which inherits from A. Now both have an "initialize" method, meaning it gets overriden in B. Now i can not use "base.initialize" to call A's "initialize" from there. Instead im trying to call it from the lower classes constructor (so A's constructor), which gets called for all inherited classes.
So now i want to call A's "initialize" on A's constructor. But when i try that, the overriding constructor of B gets called.
So is there something to tell VS (or c#) that i'm explicitly calling the methods of the class im currently in (this.method() didn't work)?
If you mark a method Initialize as virtual, that means that a derived class is free to override that method, potentially not calling base.Initialize in the process. If it is not okay if that scenario occurs, then don't mark the method as virtual.
In your case, it sounds like you just need two private Initialize methods in each class:
public class A
{
public A()
{
Initialize();
}
private void Initialize()
{
}
}
public class B : A
{
public B()
{
Initialize();
}
private void Initialize()
{
}
}
Alternatively, you might want to have a look at the Template Method design pattern. You could design your classes like this:
public class A
{
public A()
{
Initialize();
}
private void Initialize()
{
// Initialize the base class A.
// Then call DerivedInitialize. If this is actually a derived object,
// DerivedInitialize will initialize the derived instance. Otherwise,
// it won't do anything.
DerivedInitialize();
}
protected virtual void DerivedInitialize()
{
}
}
public class B : A
{
public B()
{
Initialize();
}
protected override void DerivedInitialize()
{
// Initialize B-specific stuff...
}
}
Put contents of your A.initialize() to a new private nonvirtual method. Call this new method from A's constructor and A.initialize().
Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper