I have an Abstract class and Derived class. An abstract class defines an abstract property called Message. In a derived class, a property is implemented by overriding the abstract property. The constructor of the derived class takes a string argument and assigns it to the Message property. In Resharper, this assignment leads to the warning "Virtual call of the participant in the constructor".
AbstractClass has this definition:
public abstract class AbstractClass { public abstract string Message { get; set; } protected AbstractClass() {} public abstract void PrintMessage(); }
And DerivedClass is as follows:
using System; public class DerivedClass : AbstractClass { private string _message; public override string Message { get { return _message; } set { _message = value; } } public DerivedClass(string message) { Message = message;
I found other questions about this warning, but in these situations there is an actual method call. For example, in this question , Matt Howels answer contains sample code. I will repeat this here for convenience.
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()); } }
Matt does not describe what error the warning should appear, but I assume that it will be when calling DoSomething in the Parent constructor. In this example, I understand what is meant by the name of the virtual principal. The participant is called in the base class in which only the virtual method exists.
In my situation, however, I do not understand why assigning the value Message will cause a virtual member. Both the invocation and implementation of the Message property are defined in a derived class.
Although I can get rid of the error by creating my Derived Class sealed , I would like to understand why this situation leads to a warning.
Update Based on Brett's answer, I did my best to create a ChildClass derived from DerivedClass, which would ultimately result in an exception. Here is what I came up with:
using System; public class ChildClass : DerivedClass { private readonly string _foo; public ChildClass() : base("Default ChildClass Message") { _foo = "ChildClass foo"; } public override string Message { get { return base.Message; } set { base.Message = value; Console.WriteLine(_foo.ToUpper() + " received " + value); } } }
Of course, itโs a little silly to use _foo in the Message setter, but the fact is that ReSharper does not see anything bad in this class.
If, however, you try to use ChildClass in such a program:
internal class Program { private static void Main() { var childClass = new ChildClass(); childClass.PrintMessage(); } }
When you create a ChildClass object, you will get a NullReferenceException. The exception will be thrown by ChildClass trying to use _foo.ToUpper() , because _foo is not yet initialized.