"Virtual member call in a constructor" caused by abstract members [duplicate] - c#

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

Related

Confusing about hiding method c# [duplicate]

Can anybody tell the working of overriding and hiding in terms of memory and references.
class A
{
public virtual void Test1() { //Impl 1}
public virtual void Test2() { //Impl 2}
}
class B : A
{
public override void Test1() { //Impl 3}
public new void Test2() { Impl 4}
}
static Main()
{
A aa=new B() //This will give memory to B
aa.Test1(); //What happens in terms of memory when this executes
aa.Test2(); //-----------------------SAME------------------------
}
Here memory is with class B but in the second statement aa.Test2 class A's method will be called. Why is it? If B has memory then B's method should be called (in my point of view).
Any link / exercise that describes this fundamental very deeply and completely will be a big help.
Take a look at this answer to a different question by Eric Lippert.
To paraphrase (to the limits of my comprehension), these methods go into "slots". A has two slots: one for Test1 and one for Test2.
Since A.Test1 is marked as virtual and B.Test1 is marked as override, B's implementation of Test1 does not create its own slot but overwrites A's implementation. Whether you treat an instance of B as a B or cast it to an A, the same implementation is in that slot, so you always get the result of B.Test1.
By contrast, since B.Test2 is marked new, it creates its own new slot. (As it would if it wasn't marked new but was given a different name.) A's implementation of Test2 is still "there" in its own slot; it's been hidden rather than overwritten. If you treat an instance of B as a B, you get B.Test2; if you cast it to an A, you can't see the new slot, and A.Test2 gets called.
To add to #Rawling's answer, practical examples could be shown using an example such as this:
class Base
{
// base property
public virtual string Name
{
get { return "Base"; }
}
}
class Overriden : Base
{
// overriden property
public override string Name
{
get { return "Overriden"; }
}
}
class New : Base
{
// new property, hides the base property
public new string Name
{
get { return "New"; }
}
}
1. Overriding
In case of the overriden property, base class' virtual method's slot is replaced by a different implementation. Compiler sees the method as virtual, and must resolve its implementation during run-time using the object's virtual table.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new Overriden();
// Base.Name is virtual, so the vtable determines its implementation
Console.WriteLine(b.Name); // prints "Overriden"
Overriden o = new Overriden();
// Overriden.Name is virtual, so the vtable determines its implementation
Console.WriteLine(o.Name); // prints "Overriden"
}
2. Hiding
When a method or a property is hidden using the new keyword, the compiler creates a new non-virtual method for the derived class only; base class' method remains untouched.
If the type of the variable is Base (i.e. only contains the virtual method), its implementation will be resolved through the vtable. If the type of the variable is New, then the non-virtual method or property will be invoked.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new New();
// type of `b` variable is `Base`, and `Base.Name` is virtual,
// so compiler resolves its implementation through the virtual table
Console.WriteLine(b.Name); // prints "Base"
New n = new New();
// type of `n` variable is `New`, and `New.Name` is not virtual,
// so compiler sees `n.Name` as a completely different property
Console.WriteLine(n.Name); // prints "New"
}
3. Summary
If a part of your code accepts the base type, it will always use the virtual table during run-time. For most OOP scenarios, this means that marking a method as new is very similar to giving it a completely different name.
4. Object sizes after instantiation
Note that instantiating any of these types doesn't create a copy of the virtual table. Each .NET object has a couple of bytes of header and a pointer to the virtual table of table of its type (class).
Regarding the new property (the one which is not virtual), it is basically compiled as a static method with thiscall semantics, meaning that it also doesn't add anything to the size of the instance in memory.
Already answered at here
Overriding is the definition of multiple possible implementations of the same method signature, such that the implementation is determined by the runtime type of the zeroth argument (generally identified by the name this in C#).
Hiding is the definition of a method in a derived type with a signature identical to that in one of its base types without overriding.
The practical difference between overriding and hiding is as follows:
Hiding is for all other members (static methods , instance members, static members). It is based on the early binding . More clearly , the method or member to be called or used is decided during compile time.
•If a method is overridden, the implementation to call is based on the run-time type of the argument this.
•If a method is simply hidden, the implementation to call is based on the compile-time type of the argument this.
Here are some samples : Example # 1. and Example # 2
Test1() method in class A and test1() method in class B will executes according to MethdOverriding.
Test2() method in class A and test2() method in class B will executes according to Method Hiding.
In method Overriding the child class members will execute, and in Method Hiding the Parent class members will execute.
Put simply when overriding a method or property the override method must have the same signature as the base method. When hiding this is not required, the new object can take any form as shown below
// base
public int GrossAmount { get; set; }
// hiding base
public new string GrossAmount
{
get;
set;
}
Deducting from the code provided you should have B:A.
You can hide a method in case when you want create your own implementation of the (say) method of the base class, which can not be overriden, cause, say, it's not virtual.
In my expirience, I used hiding mostly for debug purposes.
For example when I don't know who sets the property of some 3rd prt component, whom code is not available to me. So what I do is:
create a child class from the component
hide the property of interest with new keyword
put the breakpoint in set
and wait when it will be hit.
Sometimes, very useful and helps me get information in fast way, especially in first stage when you're learning new components, frameworks, libraries.. whatever.
By hiding a method or a property you are simply stating that you want to stop such method being polymorphic when you have an object of that type. Additionally hidden methods are called in a non polymorphic way so to call these method type has to be know at compile time, as it was a simply non virtual method.
public class BaseClass
{
public void PrintMethod()
{
Console.WriteLine("Calling base class method");
}
}
public class ChildClass
{
public new void PrintMethod()
{
Console.WriteLine("Calling the child or derived class method");
}
}
class Program
{
static void Main()
{
BaseClass bc = new ChildClass();
bc.PrintMethod();
}
}
Method Hiding is that when Base Class reference variable pointing to a child class object. It will invoke the hidden method in base Class.
Where as, When We declare virtual method in the base class. We override that method in the derived or child class. Then Base Class reference variable will call the derived class method. This is called Method Overriding.
class Base {
int a;
public void Addition() {
Console.WriteLine("Addition Base");
}
public virtual void Multiply()
{
Console.WriteLine("Multiply Base");
}
public void Divide() {
Console.WriteLine("Divide Base");
}
}
class Child : Base
{
new public void Addition()
{
Console.WriteLine("Addition Child");
}
public override void Multiply()
{
Console.WriteLine("Multiply Child");
}
new public void Divide()
{
Console.WriteLine("Divide Child");
}
}
class Program
{
static void Main(string[] args)
{
Child c = new Child();
c.Addition();
c.Multiply();
c.Divide();
Base b = new Child();
b.Addition();
b.Multiply();
b.Divide();
b = new Base();
b.Addition();
b.Multiply();
b.Divide();
}
}
Output : -
Addition Child
Multiply Child
Divide Child
Addition Base
Multiply Child
Divide Base
Addition Base
Multiply Base
Divide Base
At the time of overriding the compiler checks the object of the class but in
in hiding compiler only checks the reference of the class

What type does the 'this' keyword actually refer to?

I have the following code
public class Base {
public Base() {}
public virtual void IdentifyYourself() {
Debug.Log("I am a base");
}
public void Identify() { this.IdentifyYourself(); }
}
public class Derived : Base {
public Derived() {}
public override void IdentifyYourself() {
Debug.Log("I am a derived");
}
}
I run the following test code in a different entrypoint:
Base investigateThis = new Derived();
investigateThis.Identify()
and the output is: "I am a derived"
So no matter where the C# 'this' keyword is used; does it always refer to the run-time type no matter what scope 'this' is used in?
Bonus points to anyone who was able to 'Google' better than me and find MSDN documentation on specifically 'this' (pun intended) behavior.
Lastly, does anyone happen to know what is happening under the hood? Is it just a cast?
Update #1: Fixed typo in code; With the current set of answers, I guess I did not fully understand the implications of what the MSDN documentation meant by "..is the current instance..".
Update #2: Apologies, I wasn't sure if I should have made a separate question, but on further investigation, I've confused myself again; given this updated code, why is the output both: "I am a derived" & "It is a base!".
Didn't other people answer that 'this' is indeed the run-time type? Let me know if my updated question still is not clear.
Updated code:
public class Base {
public Base() {}
public virtual void IdentifyYourself() {
Debug.Log("I am a base");
}
//Updated the code here...
public void Identify() { this.IdentifyYourself(); AnotherTake(); }
public void AnotherTake() { WhatIsItExactly(this); }
public void WhatIsItExactly(Derived thing) {
Debug.Log("It is a derived!");
}
public void WhatIsItExactly(Base thing) {
Debug.Log("It is a base!");
}
}
public class Derived : Base {
public Derived() {}
public override void IdentifyYourself() {
Debug.Log("I am a derived");
}
}
Absolutely! investigateThis refers to an instance of Derived.
So the virtual method IdentifyYourself in Derived will be called. This is run-time polymorphism in effect.
The scope does not matter.
Under the hood, an virtual function table is built, and there is a pointer in the object that points to that table.
if you google: c# this the following link is the first result returned.
https://msdn.microsoft.com/en-us/library/dk1507sz.aspx
The this keyword refers to the current instance of the class and is
also used as a modifier of the first parameter of an extension method.
You may also want to take a look at base while you are at it.
https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx
The base keyword is used to access members of the base class from
within a derived class:
Call a method on the base class that has been overridden by another
method.
Specify which base-class constructor should be called when creating
instances of the derived class.
'this' always refers to the current instance, whereas 'base' always refers to the inherited type, regardless of whether the code using 'this' is in the base or the child class, it will always refer to the child (unless the base is instantiated itself, of course). It's just a reference to the current instance, like 'self' in python. Useful if a parameter has the same name as a private field, but as far as I'm aware it has no functional purpose other than that, I use it for readability, to clearly show when something belongs to the class I'm working in.

How to tell if MemberInfo represents an override

Given the following code:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public override void Method() { }
}
...
var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];
Is it possible to determine if the derivedMethodInfo represents a method declaration which overrides another in a base class?
In another question it was observed that had Method been declared abstract (and not implemented) in the base class, derivedMethodInfo.DeclaringType would have turned up as Base, which makes sense after reading #EricLippert's comments. I noticed that in the present example, since the derived class re-declares the method, that derivedMethodInfo.DeclaringType == derivedMethodInfo.ReflectedType, viz. Derived.
There doesn't seem to be any connection between baseMethodInfo and derivedMethodInfo, other than their names are the same and their respective declaring types appear in the same inheritance chain. Is there any better way to make the connection?
The reason I ask is that there appears to be no way to distinguish, through reflection, between the earlier example and the following one:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public new void Method() { }
}
In this case as well, the Derived class both declares and reflects a member called Method.
A method shadowing a virtual method will have the VtableLayoutMask flag set in Attributes.
Note that an ordinary virtual method (with no similar name from a base type) will also have this flag set.
This flag appears to indicate that the method introduces a new entry in the VTable.
There's a more specific class MethodInfo which derives from MemberInfo. Note that not all kinds of members can be virtual (fields cannot, for example).
If you say
var derivedMethodInfo = typeof(Derived).GetMethod("Method");
then you can check if
derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo
or not. See documentation for GetBaseDefinition() where they also have a code example.

Force base method call

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

What's the difference between an abstract class, and a class with only protected constructors? (.NET)

What are all the difference between an abstract class, and a class with only protected constructor(s)? They seem to be pretty similar to me, in that you can't instantiate either one.
EDIT:
How would you create an instance in a derived class, with a base class with a protected constructor? For instance:
public class ProtectedConstructor
{
protected ProtectedConstructor()
{
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor(); // this is fine
}
}
public class DerivedClass : ProtectedConstructor
{
public void createInstance()
{
ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
}
public static ProtectedConstructor getInstance()
{
return new ProtectedConstructor(); // doesn't compile
}
}
You can instantiate a class with protected constructors from within the class itself - in a static constructor or static method. This can be used to implement a singleton, or a factory-type thing.
An abstract class cannot be instantiated at all - the intent is that one or more child classes will complete the implementation, and those classes will get instantiated
Edit:
if you call ProtectedConstructor.GetInstance(); instead of new ProtectedConstructor();, it works. Maybe protected constructors can't be called this way? But protected methods certainly can.
Here is an interesting article on the topic.
Most of the time, there is little practical difference, as both are only able to be generated via a subclass.
However, marking a class abstract has two benefits:
With protected constructors, it's still possible to create an instance of the class in two ways. You can use Activator.CreateInstance with BindingFlags.NonPublic, or you can use a factory method defined in the class (or a subclass) to create an instance of the class. A class marked abstract, however, cannot be created.
You are making your intention more clear by marking the class abstract. Personally, I find this the most compelling reason to do so.
From an outside , black-box perspective, yes they are similar in that you cannot instantiate either one. However, you can never instantiate an abstract class, where you can construct a class with only protected constructors from within the class itself, or from an inheritor.
An abstract class can have abstract methods; methods that consist only of the method signature, but no body, that child classes must implement.
Seriously, not one person mentioned that yet?
Your example is flawed because in the getInstance case because you construct a ProtectedConstructor class and expect to down cast it as a DerivedClass. Instead you need a slightly more complete implementation where the derived class has a constrcutor:
public class ProtectedConstructor
{
protected ProtectedConstructor(string arg)
{
// do something with arg
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor("test");
}
}
public class DerivedClass : ProtectedConstructor
{
protected DerivedClass(string arg) : base(arg)
{
}
public void createInstance()
{
DerivedClass p = new DerivedClass("test");
}
public static DerivedClass getInstance()
{
return new DerivedClass("test");
}
}
Regardless the major difference usage of abstract classes is to define abstract methods that subclasses must implement but you don't want to provide a default implementation for. For example suppose you have some kind of Thread class that has a Run method. You want to ensure that every call to Run first setups up some logging then does the real work of the thread and then stops logging. You could write an abstract Thread class like this:
public abstract Thread
{
protected Thread()
{
}
public void Run()
{
LogStart();
DoRun();
LogEnd();
}
protected abstract DoRun();
private void LogStart()
{
Console.Write("Starting Thread Run");
}
private void LogEnd()
{
Console.Write("Ending Thread Run");
}
}
public class HelloWorldThread : Thread
{
public HelloWorldThread()
{
}
protected override DoRun()
{
Console.Write("Hello World");
}
}
Another thing to consider, that I didn't see other people mention, is that your code may be maintained in the future. If the maintainer adds a public constructor to a class, then it can be instantiated. This might break your design, so you should prevent it (or design to accommodate it).
To prevent other people from making these kinds of changes, you can comment your code. Or, as other people said, use "abstract" to explicitly document your intent.
Well, the first difference that comes to mind is that an abstract class can not be instantiated, but a class with protected constructors could be instantiated throw another public method.
A common example of this might be something like the Singleton pattern: http://en.wikipedia.org/wiki/Singleton_pattern
if you inherit an abstract class from another abstract class, you do not have to satisfy abstract methods, but you do with a normal class with protected ctors. Examples
public abstract class Parent
{
protected abstract void AMethod();
}
public abstract class Child: Parent
{
// does not implement AMethod, and that's ok
}
public class Child2: Parent
{
// does not implement AMethod, and that will cause a compile error
}
If your intent is to only allow static uses of the class (i.e. not to use it as a pure base class) then you should use the static keyword instead; the CLR will prevent instances of the class being created via any method including Reflection (AFAIK).

Categories

Resources