NullReferenceException in C# when the container is initialized - c#

In the C# code listed below, I get a "NullReferenceException" with the error:
"Object reference not set to an instance of an object"
I guess the error is related to the inheritance and/or the template definitions. The list gets initialized, and when debugging I can confirm that the list does not point to NULL. I can't figure out how to do this in another way. (Sorry about the confusing class names / structure). The exception happens here: this.localSMT.doSomething(base.list);
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
}
}
public class VTEST_FSUB<V> : VTEST<V>
{
public VTEST_FSUB()
{
do_virtual();
}
public void do_virtual()
{
this.localSMT.doSomething(base.list);
}
}
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB();
}
}
public class LocalSMT<V>
{
public LocalSMT() { }
public virtual void doSomething(List<V> value) { }
}
public class VTEST_SUB : LocalSMT<int>
{
public VTEST_SUB(){}
public override void doSomething(List<int> value) {
System.Console.WriteLine("VTEST_SUB VIRTUAL");
}
}
class Program
{
Program() {}
static void Main(string[] args)
{
VTEST_RUN run = new VTEST_RUN();
}
}

The problem is that the VTEST_FSUB<V> constructor body is executing before the VTEST_RUN constructor body. So when do_virtual is called, localSMT is still null. Then do_virtual tries to call a method on localSMT, hence the exception.
Basically the initialization order for any class in the hierarchy is:
Initialize variables which have been declared within an initializer at the point of declaration (any other variables just have the variable type's default value)
Chain up to the base class initialization
Execute the constructor body
See my article on constructor chaining for more details.
Lessons to learn:
Avoid public fields. If you use private fields, it's easy to find every piece of code that reads them and writes to them
Ideally, use readonly fields: if you'd passed the value up the constructor chain and set it in the VTEST<V> constructor, you wouldn't have had a problem. (Admittedly readonly fields can still be a pain because of the next point...)
Avoid virtual method calls in constructors. In this case that wasn't the problem, but you could easily have had the same issue if do_virtual had been abstract in VTEST_FSUB<V> and overridden to call localSMT.doSomething in VTEST_RUN. It would still have executed before the constructor body had run, which would be surprising. Anything you call within a constructor is operating on a partially-initialized object, which is a precarious situation.
Avoid large inheritance hierarchies. They're a pain to work with and reason about.
Follow .NET naming conventions! Your code is partly hard to read because it's so unidiomatic. Even when you're just giving sample code, at least follow the capitalization conventions.

try:
public void do_virtual()
{
localSMT=new LocalSMT<V>();
localSMT.doSomething(list);
}
in public class VTEST_FSUB<V> : VTEST<V>
You are not instatianing localSMT before using, so it's not working.
EDIT: OR
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
localSMT = new LocalSMT<V>();
}
}
initialize it in constructor, preferable.
Second solution is cleaner.

public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB(); // BAD! localSMT isn't initialized yet!
}
}
I believe that you have failed to new up one of your objects:
public void do_virtual()
{
localSMT = new LocalSMT<V>();
localSMT.doSomething(list);
}
Make sure that when you are trying to use an object that you initialize them! And don't worry too much, this is a very common problem in coding.

Related

Is there a way to automatically get a reference to the object calling the constructor?

Right now in my code, I have an abstract class, which contains a nested class. In the constructor of every class implementing my abstract class, I will have to construct an instance of the nested class, and pass a reference to the current object to the nested class, as demonstrated below.
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo()
{
this.SpecialStuff = new SpecializedClass(this, "stuff"); // <= This is the issue
// More stuff
}
}
As you can see, whenever I need to call new SpecializedClass(), I have to pass a reference to this. Is there a way to do this automatically, so the classes inheriting from MainClass don't need to keep passing references down?
There answer is basically no. The stack frame does not contain a reference to the calling object (if any), there is no way to get at it fundamentally unless you pass it in, or want to walk the stack (bad idea).
There are however situations where you can use expression trees for more complicated less trivial problems. however, they hardly apply here, and would be more printable characters anyway.
I guess another approach would be an extension methods, however you are just kicking the this ball up the road and creating more code for no good reason
Which leaves with a instance method or base class...
Lastly, although common, I would double check you actually need the calling object. This can easily brush up on design issues such as the Single Responsibility principle (SRP) and Separation of concerns (SOC) among others
All things being equal, if you need it then just pass it in.
No, this is not possible.
Think about it: You could run SpecialStuff = new SpecializedClass(this, "stuff"); in a static function. Then what would the value of this be?
It seems that you could push that functionality into the base abstract class.
Now you only need to call the SpecializedClass and pass this once
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
public MainClass(object stuff)
{
this.SpecialStuff = new SpecializedClass(this, stuff);
}
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo() : base("stuff")
{
// More stuff
}
}

Derived constructor with type parameter

EDIT: added follow up question from getting a solution suggested from another question
EDIT2: I just realised that my follow up question was not needed.
Is it possible to have an abstract base class with a type parameter of T have a constructor that takes a parameter of T and assigns it to a property of T? What i want to achieve is that all derived classes has a constructor that does this?
Something like:
public abstract class NotificationBase <T>
{
public string Text { get; set; }
public T Context { get; set; }
public NotificationBase(T context, string text)
{
Context = context;
Text = text;
}
}
public class NumberNotification : NotificationBase<int>{}
public class Program
{
public void Run()
{
var thing = new NumberNotification(10, "Hello!");
}
}
EDIT:
I got a link to another question that explained how to do this which is great. However i have some issues with that. And i dont mean its wrong, if that is the only way to do it then thats how it is. However its not the ideal situation for what im trying to do. I explain. This was the solution:
public class Base
{
public Base(Parameter p)
{
Init(p)
}
void Init(Parameter p)
{
// common initialisation code
}
}
public class Derived : Base
{
public Derived(Parameter p) : base(p)
{
}
}
..which works great. However it does create two small issues that id like to se if they can be addressed.
What i want is to force all classes that derives from the base to pass a T into the constructor so that its mandatory. With this solution, its possible to leave it out.
If all classes should do this then it feels redundant to create a constructor to propagate a mandatory parameter.
EDIT: I just realised that demanding a constructor that propagates the type parameter IS what im looking for. I makes sure that the T property gets a value and also allows for other things to happen in the constructor.
Yes, you can, you just need to propagate the constructor chain using the relevant type, and call the ancestor if needed:
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
: base(context, text)
{
}
}
Without constructor in child class, the instantiation you wrote can't compile because you don't offer a way for the compiler to know what to do.
You can also offer any other constructor needed.
Therefore now this compiles and works:
var thing = new NumberNotification(10, "Hello!");
Inheritance And Constructors (C# Corner)
base (C# Reference)
Define the parameterized constructor for NumberNotification class which should invoke the required constructor of NotificationBase using base
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
:base(context, text)
{
}
}
Now for NumberNotification object, context is type of int as here T is marked as int type which Yyou can check using below code:
var thing = new NumberNotification(10, "Hello!");
Console.WriteLine(thing.Context.GetType());
The above prints the output as System.Int32
Check the fiddle - https://dotnetfiddle.net/keufQO

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

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

Using parameter in constructors C#

I'm abit new in C#. I have some code like this:
namespace Example
{
public partial class Example_Setting : Form
{
public Example_Setting(String somethings)
{
}
private myPlace()
{
MessageBox.Show(somethings);
}
}
I don't know how to get value of somethings variable in myPlace().How can I do?
An example would be:
namespace Example
{
public partial class Example_Setting : Form
{
string somethings; // <-- declare a variable in the class
public Example_Setting(String somethings)
{
this.somethings = somethings; // save param to variable
}
private myPlace()
{
MessageBox.Show(somethings); // now data is here for use
}
}
I think you can use below code.Declaring the other variable and assign it into constructore and then you can use it in whole class.
public partial class Example_Setting : Form
{
public string some;
public Example_Setting(String somethings)
{
this.some = something;
}
private myPlace()
{
MessageBox.Show(this.some);
}
}
Others have already demonstrated an example. I just want to point out why you can't access somethings from myPlace.
In the example provided in your question, somethings is scoped locally to the constructor. That is, once the constructor has completed, somethings is no longer available to reference and use. In the examples others have provided, they scope somethings to the class, and then assign a the value provided in the constructor parameter. Since somethings is scoped to the class, your other methods (and properties) can access it. Note that if you use public, others outside of the class can use it as well. Best practice though is to keep it private and if you need public access, to use a property.

Is it possible to create an instance of an class without running ANY code from the class? (no ctor, no field initializations)

I have created an engine that takes in 3rd party plugins (DLL's) that implement an interface.
Since I have no control over the code that gets plugged in, I want to be able to run 1 specific method (from the interface) from the correct class (GetTypes loop untill I find the interfaced class ).
Since anyone can create nice constructor code that executes on Activator.CreateInstance, I can solve that by using FormatterServices.GetUninitializedObject. But that does not help when code is being initialized on fields in the class.
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
//I only want this run.
public string MyProperty{
get {
return "ANiceConstString";
}
}
}
The problem with both ways (CreateInstance/GetUninitializedObject) is that the constructor of someotherclass will be run.
Before you start analyze my needs. This is only run in the initializing of the engine to get a set of standard values. If this get'er relies on other initialized values the "plugin" will be marked as failed as there is no valid value returned. If not marked as failed, later on the class will be loaded properly with Activator.CreateInstance().
So stick to this question:
Does .Net support any way to create an 100% non-initialized class?
Update for the answers. I tested this before I posted my question.
For the answer that someotherclass wont run, I allready tested that and it is run if static.
public class myclass : myinterface {
static Tutle test;
public myclass () {
test = new Tutle();
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject does not.
public class myclass : myinterface {
static Tutle test = new Tutle();
public myclass () {
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject shows the messagebox.
Is there a way to get around static field intializers and ctors?
Simply:
var obj = (myclass)FormatterServices.GetUninitializedObject(typeof(myclass));
That will not run the constructor / field initializers. At all. It will not run the constructor for someotherclass; name will be null.
It will, however, execute any static constructor that exists, if necessary under standard .NET rules.
HOWEVER! I should note that this method is not intended for ad-hoc usage; its primary intent is for use in serializers and remoting engines. There is a very good chance that the types will not work correctly if created in this way, if you have not subsequently taken steps to put them back into a valid state (which any serializer / remoting engine would be sure to do).
As an alternative design consideration:
[SomeFeature("ANiceConstString")]
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
}
Now you can access the feature without instantiation; just use:
var attrib = (SomeFeatureAttribute)Attribute.GetCustomAttribute(
type, typeof(SomeFeatureAttribute));
string whatever = attrib == null ? null : attrib.Name;
with:
[AttributeUsage(
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public sealed class SomeFeatureAttribute : Attribute
{
private readonly string name;
public string Name { get { return name; } }
public SomeFeatureAttribute(string name) { this.name = name; }
}

Categories

Resources