I'm getting StackOverflowException when I run below program. My doubt is how this program recursively calling each classes(ArrayTest1, ArrayTest2) fields without executing constructor method?
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var arraryTest = new ArrayTest1();
}
}
public class ArrayTest1
{
ArrayTest2 arrayTest2 = new ArrayTest2();
public ArrayTest1()
{
Console.WriteLine($"{nameof(ArrayTest1)} Class Contructor Executed");
}
}
public class ArrayTest2
{
ArrayTest1 arrayTest1 = new ArrayTest1();
public ArrayTest2()
{
Console.WriteLine($"{nameof(ArrayTest2)} Class Contructor Executed");
}
}
Because you create an infinite chain of ArrayTest1 -> ArrayTest2 -> ArrayTest1 -> ArrayTest2 -> ...
To understand why you are not getting any output, see C# constructor execution order
Important steps in your case (no inheritance involved):
Member variables are initialized to default values
Variable initializers are executed
The constructor bodies are executed
You never reach constructor bodies, as the stack overflow happens in variable initializer
Because when you do this:
new ArrayTest1()
You are creating an instance of ArrayTest1. Which does this:
ArrayTest2 arrayTest2 = new ArrayTest2();
This creates an instance of ArrayTest2. Which does this:
ArrayTest1 arrayTest1 = new ArrayTest1();
This creates an instance of ArrayTest1. Which does this:
ArrayTest2 arrayTest2 = new ArrayTest2();
This creates an instance of ArrayTest2. Which does this:
ArrayTest1 arrayTest1 = new ArrayTest1();
This creates an instance of ArrayTest1...
And so on, indefinitely.
It's not clear what your goal is with the code. But what is clear is that your objects can't mutually depend on one another this way because the simple act of creating an instance of the object results in an infinite recursion.
Given only the code shown, the solution is to simply remove those mutually-dependent fields from the classes, since nothing ever uses them anyway:
public class ArrayTest1
{
public ArrayTest1()
{
Console.WriteLine($"{nameof(ArrayTest1)} Class Contructor Executed");
}
}
public class ArrayTest2
{
public ArrayTest2()
{
Console.WriteLine($"{nameof(ArrayTest2)} Class Contructor Executed");
}
}
Related
Problem
When I instantiate an instance of the Service class - derived from the ServiceBase class - the constructor I create for the Service class is skipped during instantiation. Then when the line "private ServiceController controller..." is hit, it fails because the ConfigStream object is never passed to the Service class variable _configstream. I don't have issues with constructors being skipped elsewhere in my code. Is this related to the use of the base class ServiceBase?
I've tried including the base class constructor like:
public Service(ConfigStream configstream) : base() {}
It doesn't produce any different result. From what I've read, that makes sense because the default constructor of the base class should be called by default.
I've included the beginning of both my Service class and ConfigStream. ConfigStream utilizes its constructors without any issue, but its also not inheriting any classes.
Code
public static class MainClass
{
static void Main(String[] args)
{
// Test if input arguments were supplied
if (args.Length > 0)
{
// if arguments supplied, use the supplied config file path (second cli argument)
if (args[0] == "-i")
{
// ConfigStream configstream = new ConfigStream(args[1]);
ServiceBase.Run(new Service(new ConfigStream(args[1])));
}
}
else
{
// otherwise run service without arguments
// the config will be assumed in the same directory
Service service = new Service(new ConfigStream());
ServiceBase.Run(service);
}
}
}
public class Service : ServiceBase
{
// class instantiation
private Thread processThread;
private Process process;
// Instance variables
private static ConfigStream _configstream;
// Function: Service
// Purpose: Class Constructor
public Service(ConfigStream configstream)
{
// assign ConfigStream instance
_configstream = configstream;
// set global service name and description for use by installer
GlobalVariables.setServicename(_configstream.getSetting("Service Name"));
GlobalVariables.setServicedesc(_configstream.getSetting("Service Description"));
ServiceName = _configstream.getSetting("Service Name");
//setting logger level
logger.setLogLevel(0);
logger.info("System Event", "Starting service");
processThread = new Thread(ProcessManager);
processThread.Start();
}
private ServiceController controller = new ServiceController(_configstream.getSetting("Service
Name"));
...
}
public class ConfigStream
{
// set properties of ConfigStream
public string config { get; private set; }
// constructor with config as an argument
public ConfigStream(string config_location)
{
string config = config_location;
}
// constructor with no arguments
public ConfigStream()
{
config = GlobalVariables.cwd + "\\" + GlobalVariables.configFileName;
}
...
}
When I instantiate an instance of the Service class - derived from the ServiceBase class - the constructor I create for the Service class is skipped during instantiation
It is not skipped. It's just the order of initialization that causes your problem.
Member fields are initialized first, before any constructor's code is run. Thus when the initializer of controller is called, an exception is thrown because _configStream is null. See this Q&A for further information.
Side note: In addition, it is a very bad idea to have the _configStream field declared static and at the same time initialize it from the constructor every time an instance is created.
E.g. I have a class with a Process method, in this method I set up a number of things e.g.
public class messageProcessor
{
...
public string Process(string settings)
{
var elementFactory = new ElementFactory();
var strategyToUse = new legacyStrategy();
...
var resources = new messageResource(
elementFactory,
strategyToUse,
...);
}
}
Is it possible for me to create an instance of this class but when I call the Process method, replace (for example) elementFactory to be set to my mocked factory.
Is that possible and how would I do it? Thanks
If your code depends on the ElementFactory, you can inject the interface of this class through the constructor of the MessageProcessor class.
This is called "Inversion of control".
So for example you created an interface IElementFactory which you can inject into the class via the constructor like this:
public class messageProcessor
{
private readonly IElementFactory elementFactory;
public messageProcessor(IElementFactory elementFactory)
{
this.elementFactory = elementFactory;
}
public string Process(string settings)
{
var strategyToUse = new legacyStrategy();
...
var resources = new messageResource(
this.elementFactory,
strategyToUse,
...);
}
}
Now, in your test, you can inject a substitute of the IElementFactory. Like this:
public void Test()
{
var elementFactory = Substitute.For<IElementFactory>();
// tell the substitute what it should return when a specific method is called.
elementFactory.AnyMethod().Returns(something);
var processor = new messageProcessor(elementFactory);
}
At runtime your application should inject an instance of the IElementFactory into the messageProcessor class. You should do this via "Dependency injection".
I have noticed a rather weird behaviour in my application I am creating;
I have a class I defined that has a static "instance" variable of the class type.
I would assume that (as per code attached) the constructor would be called.
Alas, it is not, unless I use the Void.get in a non-static field anywhere in my code.
public class Void : TilePrototype {
public static Tile get = new Tile((int)TileEntities.Void);
public static Void instance = new Void();
public Void() {
Debug.Log("created");
id = (int)TileEntities.Void;
isBlocking = true;
register();
}
public override RenderTile render(Tile tile){
return new RenderTile(0, new Color(0, 0, 0, 0));
}
So when I have something like :
public static TileStack empty = new TileStack(Void.get, Void.get);
the Void class constructor never gets called. But, if I have:
Tile t = Void.get;
Anywhere in my code it will be called.
Why?
Thanks.
This is a really really subtle and nuanced area of C#; basically, you've stumbled into "beforefieldinit" and the difference between a static constructor and a type initializer. You can reasonably ask "when does a static constructor run?", and MSDN will tell you:
It is called automatically before the first instance is created or any static members are referenced.
Except... public static TileStack empty = new TileStack(Void.get, Void.get); isn't a static constructor! It is a static field initializer. And that has different rules, which basically are "I'll run when I must, no later, possibly sooner". To illustrate with an example: the following will not (probably) run your code, because it doesn't have to - there isn't anything demanding the field:
class Program
{
static void Main()
{
GC.KeepAlive(new Foo());
}
}
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
}
However, if we make a tiny tweak:
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
static Foo() { } // <=== added this
}
Now it has a static constructor, so it must obey the "before the first instance is created" part, which means it needs to also run the static field initializers, and so on and so on.
Without this, the static field initializer can be deferred until something touches the static fields. If any of your code actually touches empty, then it will run the static field initializer, and the instance will be created. Meaning: this would also have this effect:
class Program
{
static void Main()
{
GC.KeepAlive(Foo.empty);
}
}
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
}
This ability to defer execution of the static initialization until the static fields are actually touched is called "beforefieldinit", and it is enabled if a type has a static field initializer but no static constructor. If "beforefieldinit" isn't enabled, then the "before the first instance is created or any static members are referenced" logic applies.
Thanks to Marc Gravell's aswer I came up with this contraption (and admittedly I do like the new solution more than the old one, so thanks again!)
Modifications done to the Void class:
public class Void : TilePrototype {
public static Void instance = new Void();
public static Tile get {
get {
return new Tile(instance.id);
}
}
public Void() {
isBlocking = true;
}
public override RenderTile render(Tile tile){
return new RenderTile(0, new Color(0, 0, 0, 0));
}
}
So as You can see I made the "get" variable a property, so that it's evaluated later, when you actually need the tile, not on construction.
I've changed all "get"s this way.
Second change is in the TilePrototype:
public class TilePrototype {
public static Dictionary<int, TilePrototype> tilePrototypeDictionary = new Dictionary<int, TilePrototype>();
public static void registerPrototype(int id, TilePrototype tp){
tp.id = id;
tilePrototypeDictionary.Add(id, tp);
}
public static bool registered = false;
public static void registerAll(){
if( registered ) return;
registerPrototype(0, Void.instance);
registerPrototype(1, Air.instance);
registerPrototype(2, Floor.instance);
registerPrototype(3, Wall.instance);
(...)
Here I've added the registerPrototype and registerAll functions.
This gives me easy access to all the registered type ids (by say Wall.instance.id) as well as the other way around (from id to instance via the Dictionary)
I also have all registered things in one place, with the possibility of runtime adding more
Overall, much neater, and here I assure that all tiles are registered properly and assigned proper IDs.
Change of ID is simple and in one place and everywhere else, access to this ID is done via a short .instance.id
Thanks again for the help :)
I have the following code in a class library:
public class Manager
{
private static readonly Manager instance = new Manager();
public static IHelper Helper { get { return Manager.instance.helper; } }
[Import(typeof(IHelper))]
internal IHelper helper { get; set; }
private Manager()
{
using (DirectoryCatalog catalog =new DirectoryCatalog(#"c:\Dev\Plugins"))
{
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
I am using the above class to set custom user-interface settings at run-time, will the constructor run every time I access a member (will it scan the directory)?
An example call might be lblMask.Text = Helper.SearchMask;
The directory scanning only happens in the instance constructor. The instance constructor only happens when new Manager() is used (assuming nobody cheats with reflection), which only happens once, in the static field initializer.
So: no. It should only happen once - the first time per app-domain.
However, you could just stick in a break-point / some kind of output, and find out...
When you access the Manager class for the first time (either an instance of it or its static methods and fields), the static constructor of Manager will run and initialize the instance field.
So the next time you access the instance field, it is initialized and won't run new Manager().
In fact the C# compiler will automatically move the fields initializations to the class constructor. The following code
private static readonly Manager instance = new Manager();
will be converted to this:
private static readonly Manager instance;
static Manager()
{
instance = new Manager();
}
I am writing a class library(API) in C#. The class is non-static and contains several public events. Is it possible to trigger those events from a static method in a separate class?
For example...
class nonStaticDLLCLASS
{
public event Event1;
public CallStaticMethod()
{
StaticTestClass.GoStaticMethod();
}
}
class StaticTestClass
{
public static GoStaticMethod()
{
// Here I want to fire Event1 in the nonStaticDLLCLASS
// I know the following line is not correct but can I do something like that?
(nonStaticDLLCLASS)StaticTestClass.ObjectThatCalledMe.Event1();
}
}
I know you typically have to create an instance of the non-static class in order to access it's methods but in this case an instance has already been created, just not by the class that is trying to access it.
No, instance members can only be invoked/accessed on a valid instance of the type.
In order for this to work you must pass an instance of nonStaticDLLCLASS to StaticTestClass.GoStaticMethod and use that instance reference to invoke/access the non-static members.
In your example above how do you specify which instance of the type you are accessing? The static method has no knowdlege of any instance so how does it know which one to use or if there are any loaded in memory at all?
Consider this example:
using System;
class Dog
{
public String Name { get; set; }
}
class Example
{
static void Main()
{
Dog rex = new Dog { Name="Rex" };
Dog fluffy = new Dog { Name="Fluffy" };
}
static void sayHiToDog()
{
// In this static method how can I specify which dog instance
// I mean to access without a valid instance? It is impossible since
// the static method knows nothing about the instances that have been
// created in the static method above.
}
static void sayHiToDog(Dog dog)
{
// Now this method would work since I now have an instance of the
// Dog type that I can say hi to.
Console.WriteLine("Hello, " + dog.Name);
}
}
Instance methods can only be called on instances. In your example, the instance is calling the static method. Can you give the static method a parameter allowing the instance to pass in a reference to itself? Something like this:
class nonStaticDLLCLASS
{
public event Event1;
public CallStaticMethod()
{
StaticTestClass.GoStaticMethod(this);
}
}
class StaticTestClass
{
public static GoStaticMethod(nonStaticDLLCLASS instance)
{
// Here I want to fire Event1 in the nonStaticDLLCLASS
// I know the following line is not correct but can I do something like that?
instance.Event1();
}
}
I think you need to clarify your question to specify why you can't do something like this, or why the instance can't raise its own event.