-2

What I have is:

public static class IDs {

    public static string someID { get; set; }

    static IDs() {
        log.info(someID);
        // use someID here
    }
}

public class otherClass {

     public void otherMethod(string sym) {
         IDs.someID = sym;
     }
}

and then using an instance of otherClass like this:

otherClassInstance.otherMethod("someStringSymbol");

I dont have any build errors, but log.info(someID); is printing null.
I was expecting it to be someStringSymbol.

Tommaso Bertoni
  • 2,333
  • 1
  • 22
  • 22
user1207289
  • 3,060
  • 6
  • 30
  • 66
  • 2
    The order in which static constructors happen is not defined. (The order in which static *initializers* happen is, but even then not across classes.) The ill-defined order, as well as the near impossibility to recover from errors in them, should be a strong disincentive against using static constructors period, but especially when you're going to introduce dependencies. Prefer instances with a clear initialization time, even if you make those singletons. – Jeroen Mostert Jul 17 '19 at 14:34
  • https://stackoverflow.com/questions/185384/order-of-static-constructors-initializers-in-c-sharp – Renat Jul 17 '19 at 14:34
  • The code you posted does not compile. Please edit your question with a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Joe Sewell Jul 17 '19 at 14:36
  • 2
    The static constructor is called before the `someID` property is set. This is the expected behaviour. The property cannot be set before the type has been initialized. – mm8 Jul 17 '19 at 14:37
  • what are you trying to achieve? – Tommaso Bertoni Jul 17 '19 at 14:41
  • I am trying to get `someStringSymbol` in `IDs` constructor so I can utilize it in `IDs` class. All this ,if possible, without changing `IDs` class to non-static – user1207289 Jul 17 '19 at 14:45
  • why in the constructor? if the variable is static, you could have a (private) static method that uses that field whenever it gets a new value set... is this what you'd like to do? – Tommaso Bertoni Jul 17 '19 at 15:56
  • Per my understanding , I put that in constructor because of my comment below – user1207289 Jul 17 '19 at 16:06

2 Answers2

3

This is because the static constructor is called automatically before the first instance is created or any static members are referenced..

This means that when an instance of otherClass invokes IDs.someID = sym; the first operation that gets executed is the static constructor, i.e. the code inside static IDs().

At this point the static variable has not yet been initialized, and you are basically executing log.info(null);.

After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod, after the first reference of IDs.


Given the OP's requirement:

I want to use the value passed in someID in a switch statement

The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:

public static class IDs
{
    private static string _someID; // backing field

    public static string SomeID
    {
        get { return _someID; }

        set
        {
            _someID = value;
            DoSomethingWithSomeID();
        }
    }

    private static DoSomethingWithSomeID()
    {
        // Use SomeID here.

        switch (IDs.SomeID)
        {
            ...
        }
    }
}

public class OtherClass
{
    public void OtherMethod(string sym)
    {
        // This will set a new value to the property
        // and invoke DoSomethingWithSomeID.
        IDs.SomeID = sym;
    }
}

DoSomethingWithSomeID will be invoked every time someone sets a new value to SomeID.

Tommaso Bertoni
  • 2,333
  • 1
  • 22
  • 22
  • So how can we initialize `someID` at same time as executing constructor `static IDs` – user1207289 Jul 17 '19 at 15:03
  • do you just want to log the value of `someID`? – Tommaso Bertoni Jul 17 '19 at 15:40
  • No, I want to use it in a `switch` statement and based on the value passed in `someID` from `someStringSymbol` , construct `xPath` of several UI elements in `IDs` class – user1207289 Jul 17 '19 at 15:57
  • are the references to those UI elements static fields? – Tommaso Bertoni Jul 17 '19 at 15:59
  • Yes , thats the challenge I am facing currently. Initially I used static but now as requirements changed , I need to construct `xPath` dynamically – user1207289 Jul 17 '19 at 16:00
  • @user1207289 I edited my answer, see if it solves your problem. – Tommaso Bertoni Jul 17 '19 at 16:12
  • I have not tried it yet , I am going to now , but what if these `xPaths` are not in a method. Will I require to put them in `DoSomethingWithSomeID` method. Currently they are just in class `IDs` , not in a method. – user1207289 Jul 17 '19 at 16:39
  • It's fine as long as these `XPath`s are static – Tommaso Bertoni Jul 17 '19 at 16:41
  • It goes inside `DoSomethingWithSomeID` and prints value of `SomeID` but does not gives me value of `SomeID` in `OtherClass` but it may be because of how I am accessing `xPaths` through a separate class instance. I am thinking static class may not work for this as mentioned below in one of the answer. – user1207289 Jul 17 '19 at 18:33
  • I have marked yours as an answer as it now prints the value of `SomeID` – user1207289 Jul 17 '19 at 18:36
1

I dont think what you are trying to do is suited to static classes. I would try the following

public class IDs{

    public string someID{ get; set; }

    public IDs(string someId){
        this.someID = someId;
        log.info(this.someID);
           //use someID here
    }
}

pulic class otherClass{


     public otherMethod(string sym){
                IDs id = new IDs(sym);
            }
      }

public class anotherClass{

                //access instance of otherClass in wrp and call otherMethod()
               wrp.otherMethod("someStringSymbol")
         }
S. Phillips
  • 58
  • 1
  • 5
  • If I do this , then I will have to change reference of `IDs` at several places because I am making it non-static from static. I want to avoid that. – user1207289 Jul 17 '19 at 14:55