Using a list from another method in a static class - c#

So I have a static class with a list declared as one of it's members, and I populate the list in a function lets say it's called PopulateList(). Is it possible to modify the list in another function without:
1) Calling it as a parameter
2) Instantiating it in a constructer (Trying to keep the class static. I'm working off of a template so I can't really change the structure of the classes)
Without somehow instantiating though, I will obviously receive null exceptions, so I was wondering if there is a 3rd way to do this.
public Static class MyClass{
static public List<String> m_SuiteFileNameList2=null;
public static bool Function1(inp){
//m_SuiteFileNameList2 stuff
}
public static void Function2(){
//m_SuiteFileNameList2 other stuff
}
}

You can either use a static constructor, or static initialization. It will allow you to keep your class static, but will ensure that the list is always defined:
static class MyClass
{
static MyClass()
{
MyList = new List<Whatever>();
}
// etc
}
or
static class MyClass
{
public static List<Whatever> MyList = new List<Whatever>();
}
Another option is to add a null check to every usage of the list:
public static void MyMethod()
{
if (MyList == null)
{
MyList = new List<Whatever>();
}
//etc
}

I would call a function called 'Initialize' which is static and takes care of your static members.
Though I would recommend against static members if possible.
Why?
They can lead to head aches (yes, that hurts)
Their behaviour in memory allocation is different (How is memory allocated for a static variable?)
code snippet
public static class YourClass
{
public static List<string> YourList;
public static void InitializeList()
{
YourList = new List<string>();
YourList.Add("hello");
YourList.Add("how");
YourList.Add("are");
YourList.Add("you?");
}
}
Call your Initialize-Function from outside:
YourClass.InitializeList();
EDIT: Given your code , you can also do it this way:
public Static class MyClass{
static public List<String> m_SuiteFileNameList2=null;
public static bool Function1(inp){
if(m_SuiteFileNameList2 == null)
{ m_SuiteFileNameList2 = new List<String>();}
//m_SuiteFileNameList2 stuff
}
public static void Function2(){
if(m_SuiteFileNameList2 == null)
{ m_SuiteFileNameList2 = new List<String>();}
//m_SuiteFileNameList2 other stuff
}
}

Related

Is "this" static? Checking for Static in the constructor

I need to determine if a member T of class T is a static member, in the constructor. I expect this will involve checking some attributes of "this", but I haven't been able to determine what to look for.
public class Thing
{
public static readonly List<Thing> ListOfStaticThings = new();
public static readonly Thing StaticThing1 = new ("StaticThing1");
public static readonly Thing StaticThing2 = new ("StaticThing2");
public static readonly Thing StaticThing3 = new ("StaticThing3");
public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
if(this.IsStatic) //how to determine if the thing being constructed is static?
{ ListOfStaticThings.Add(this);}
}
}
How do I identify if the Static attribute is applied to this?
*** UPDATED ***
In this example, both StaticThing and NonStaticThing will be constructed using the private constructor. However, only the StaticThing should be added to the ListOfStaticThings when constructed. The full implementation will have 20+ static readonly fields of the class type.
I've already verified that the ListOfStaticThings will contain the StaticThing.
The ListOfStaticThings has multiple uses. This is on the path to Enumeration Classes, with this list containing all the possible Things (such as account statuses) permitted by the class. In addition, the ListOfStaticThings can be passed to EFCore.HasData to seed the data in the table. It can also be used for data validation in unit testing because it contains all the data and is persisted in the model.
However, all those use cases are beyond the scope of this question. The piece I'm looking for is how to identify if the "this" being constructed is static so I can add it to the ListOfStaticThings. I want StaticThing1, 2 & 3 to be in the list, but not NonStaticThing.
*** Final Update ***
As pointed out by McAden's answer, this is not necessary because the non-static member of T cannot be added to class T without causing an infinite recursion overflow. Since only static members of T can be added, there is no need to determine if they are also static in the constructor.
I think you're going about it the wrong way - all static members should be initialized either in the property itself or in a static constructor, so I would do it this way:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1 = new Thing("StaticThing1");
public static readonly Thing StaticThing2 = new Thing("StaticThing2");
public static readonly Thing StaticThing3 = new Thing("StaticThing3");
// public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Now the instance constructor doesn't need to know if it's a "static" instance or not.
However, to be safe (meaning not rely on the order of initializers), I would also crate the static instances in the static constructor:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1;
public static readonly Thing StaticThing2;
public static readonly Thing StaticThing3;
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1 = new Thing("StaticThing1"),
StaticThing2 = new Thing("StaticThing2"),
StaticThing3 = new Thing("StaticThing3")
};
}
}
Now, if you need to know if it's "static" for some other reason, then I would create another private constructor that takes a static flag:
private Thing(string name, bool isStatic=False) : this(name)
{
if (isStatic) {
// Do different stuff for a "static" instance
}
}
but I would not put logic there to "add itself" to a static list - that can be accomplished more cleanly another way.
how [do I] prevent non-static members being added to the list
If you want to make the list immutable, then you could either expose it as an immutable type or interface like 'IEnumerable', or you could just
generate the list on the fly with a static property getter:
public static IEnumerable<Thing> ListOfStaticThings {
get {
return new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Updated Answer:
In OP's very specific preferred approach there's no point. The public Thing NonStaticThing = new("NonStaticThing"); will result in a StackOverflowException as each child will try to create another child infinitely.
In general, however, my advice to anybody trying to do something "statically" and otherwise "not" would be to use a static constructor for static things.
Original Answer based upon un-edited question:
Order of operations - The static field will be assigned before anything else outside that class can call the constructor on that class and the constructor for setting that static readonly field will be called before the static field is actually assigned. Simply check to see if the static field is null in your constructor.
private static void Main(string[] args)
{
var test = new Thing();
Console.WriteLine(test.IsStaticInstance); // False
Console.WriteLine(Thing.Instance.IsStaticInstance); // True
}
public class Thing
{
public static readonly Thing Instance = new Thing();
public Thing()
{
IsStaticInstance = Instance == null;
}
public bool IsStaticInstance { get; }
}

Why isn't my static constructor being called

I have two classes that I'm trying to use to implement a string enumeration pattern. The problem is the static constructor for the child class isn't being called when an operator of the parent class is called. Is there a way I can fix that without adding a hack to the code to initialize the static members?
public abstract class BaseStringEnum<T> where T : BaseStringEnum<T>
{
public string Value { get; private set; }
private static List<T> _values = null;
protected static List<T> Values
{
get
{
if (_values == null)
{
_values = new List<T>();
}
return _values;
}
}
protected BaseStringEnum(string value, string resId)
{
Value = value;
ResourceId = resId;
Values.Add((T)this);
}
public static implicit operator string(BaseStringEnum<T> value)
{
return value.Value;
}
public static implicit operator BaseStringEnum<T>(string value)
{
return Values.Where(v => v.Value.Trim() == value.Trim()).First();
}
}
public sealed class UseTimeStringEnum : BaseStringEnum<UseTimeStringEnum>
{
private UseTimeStringEnum(string value, string resourceId) : base(value, resourceId) { }
public static readonly UseTimeStringEnum None;// = new UseTimeStringEnum("N", "None");
public static readonly UseTimeStringEnum Required;// = new UseTimeStringEnum("R", "Required");
public static readonly UseTimeStringEnum Optional;// = new UseTimeStringEnum("O", "Optional");
static UseTimeStringEnum()
{
None = new UseTimeStringEnum("N", "None");
Required = new UseTimeStringEnum("R", "Required");
Optional = new UseTimeStringEnum("O", "Optional");
}
}
The problem is when the code tries to do something like (UseTimeStringEnum)"R" it fails because the static constructor hasn't fired yet. I feel like it should fire because I'm using a static operator.
Static constructor of some class is called once one of the following conditions is met:
Instance of the class is created;
any static field of the class is accessed.
Since you do not create instances of UseTimeStringEnum neither acess it's static fields within your code, the static constructor is not called.
So the point is: BaseStringEnum does not know of UseTimeStringEnum at the compile time.
I see the only proper solution - we can refer UseTimeStringEnum at the runtime.
I added static constructor to the BaseStringEnum class wich loads and observes all available subclasses with Reflection.
now the static constructor is called.
EDIT: Mykroft pointed there is the way to call a static constructor directly instead of referencing static fields with reflection. So i believe the final code snippet should be
static BaseStringEnum()
{
var StringEnumTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(type => type.IsSubclassOf(typeof(BaseStringEnum<T>)));
foreach (var type in StringEnumTypes) type.TypeInitializer.Invoke(null, null);
}
As others rightly pointed out my constructor isn't being called because the parent class doesn't know the child class. Fortunately in this SO question I found a snippet of code that calls the constructor explicitly.
typeof(T).TypeInitializer.Invoke(null, null);
This works for my purposes here.

Share common functionality between two static classes

I need to share some common functionality between two static classes:
public static class Class
{
public static void ClassMethod()
{
SharedMethod<object>();
}
//ideally a private method
internal static void SharedMethod<T>()
{
}
}
public static class GenericClass<T>
{
public static void GenericClassMethod()
{
SharedMethod<T>();
}
}
Is there a better design here? internal is my last choice, but really the method SharedMethod has no significance outside those two classes.
Requirements:
I can't combine them to a single class, I need them separately, one generic and other not.
The classes need not be strictly static, but they shouldn't be instantiable or inheritable.
SharedMethod can fall in either class, it doesn't matter.
This workaround doesn't meet all 3 requirements (which is impossible imo) but it made up for the same functionality I wanted.
I ended up using a single class as Marc suggested in comments. But then I had the generic class nested inside the non generic class to act for the generic functionality.
public static class Class
{
public static void ClassMethod()
{
SharedMethod<object>();
}
static void SharedMethod<T>()
{
//----
}
public static void GenericClassMethod<T>()
{
return GenericClass<T>.SharedMethod();
}
static class GenericClass<T>
{
static void SharedMethod()
{
//available here since private members of outer class is visible to nested class
SharedMethod<T>();
}
}
}
So now, even though the calling has to be done little differently from how I wanted it originally in the question, functionally both are equal.
First I thought you can't meet the 3 rules, but then I thought about reflection, and I came up with something that works, but that shouldn't be used unless you really don't have any other way of accomplishing what you need
I don't recommend using it but just for fun I'll post the code:
public static class ClassA
{
private static void sharedMethod<T>() { }
public static void ClassMethod()
{
sharedMethod<object>();
}
}
public static class GenericClass<T>
{
static MethodInfo sharedMethodInfo;
static GenericClass()
{
MethodInfo mi = typeof(ClassA).GetMethod("sharedMethod", BindingFlags.NonPublic | BindingFlags.Static);
sharedMethodInfo = mi.MakeGenericMethod(new Type[] { typeof(T) });
}
public static void GenericClassMethod()
{
sharedMethodInfo.Invoke(null, null);
}
}
Declare the classes as sealed - that way they won't be inheritable.
If you change the permission from private to protected that way anything in your application can see the method but will be invisible to another application trying to use your methods.
Hope this helps !
If you can use the singleton pattern, you can have 2 classes, with the generic class inheriting from the standard one. Also you can keep your static methods, here is what it can look like:
internal class ClassA
{
private static ClassA _instance;
private static ClassA Instance
{
get
{
if (_instance == null) _instance = new ClassA();
return _instance;
}
}
protected void sharedMethod<T>() { }
public static void ClassMethod()
{
Instance.sharedMethod<object>();
}
}
public sealed class GenericClass<T> : ClassA
{
private static GenericClass<T> _instance;
private static GenericClass<T> Instance
{
get
{
if (_instance == null) _instance = new GenericClass<T>();
return _instance;
}
}
public static void GenericClassMethod()
{
Instance.sharedMethod<T>();
}
}

C# static class constructor

Is there a work around on how to create a constructor for static class?
I need some data to be loaded when the class is initialized but I need one and only one object.
C# has a static constructor for this purpose.
static class YourClass
{
static YourClass()
{
// perform initialization here
}
}
From MSDN:
A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only. It
is called automatically before the first instance is created or any
static members are referenced
MSDN link
.
A static constructor looks like this
static class Foo
{
static Foo()
{
// Static initialization code here
}
}
It is executed only once when the type is first used. All classes can have static constructors, not just static classes.
Yes, a static class can have static constructor, and the use of this constructor is initialization of static member.
static class Employee1
{
static int EmpNo;
static Employee1()
{
EmpNo = 10;
// perform initialization here
}
public static void Add()
{
}
public static void Add1()
{
}
}
and static constructor get called only once when you have access any type member of static class with class name Class1
Suppose you are accessing the first EmployeeName field then constructor get called this time, after that it will not get called, even if you will access same type member.
Employee1.EmployeeName = "kumod";
Employee1.Add();
Employee1.Add();
Static constructor called only the first instance of the class created.
like this:
static class YourClass
{
static YourClass()
{
//initialization
}
}
We can create static constructor
static class StaticParent
{
StaticParent()
{
//write your initialization code here
}
}
and it is always parameter less.
static class StaticParent
{
static int i =5;
static StaticParent(int i) //Gives error
{
//write your initialization code here
}
}
and it doesn't have the access modifier
You can use static constructor to initialization static variable. Static constructor will be entry point for your class
public class MyClass
{
static MyClass()
{
//write your initialization code here
}
}
Static classes cannot have instance constructors (unlike the accepted answer). However, a class can have a static constructor. That is totally different.

How do I call a non-static method from a static method in C#?

I have the following code, I want to call data1() from data2(). Is this possible in C#? If so, how?
private void data1()
{
}
private static void data2()
{
data1(); //generates error
}
You'll need to create an instance of the class and invoke the method on it.
public class Foo
{
public void Data1()
{
}
public static void Data2()
{
Foo foo = new Foo();
foo.Data1();
}
}
Perhaps what you are looking for is the Singleton pattern?
public class Singleton
{
private Singleton() {}
public void DoWork()
{
// do something
}
// You can call this static method which calls the singleton instance method.
public static void DoSomeWork()
{
Instance.DoWork();
}
public static Singleton Instance
{
get { return instance; }
}
private static Singleton instance = new Singleton();
}
You still have to create an instance of the class but you ensure there is only one instance.
You have to create an instance of that class within the static method and then call it.
For example like this:
public class MyClass
{
private void data1()
{
}
private static void data2()
{
MyClass c = new MyClass();
c.data1();
}
}
You can't call a non-static method without first creating an instance of its parent class.
So from the static method, you would have to instantiate a new object...
Vehicle myCar = new Vehicle();
... and then call the non-static method.
myCar.Drive();
You just need to provide object reference . Please provide your class name in the position.
private static void data2()
{
<classname> c1 = new <classname>();
c1. data1();
}
Apologized to post answer for very old thread but i believe my answer may help other.
With the help of delegate the same thing can be achieved.
public class MyClass
{
private static Action NonStaticDelegate;
public void NonStaticMethod()
{
Console.WriteLine("Non-Static!");
}
public static void CaptureDelegate()
{
MyClass temp = new MyClass();
MyClass.NonStaticDelegate = new Action(temp.NonStaticMethod);
}
public static void RunNonStaticMethod()
{
if (MyClass.NonStaticDelegate != null)
{
// This will run the non-static method.
// Note that you still needed to create an instance beforehand
MyClass.NonStaticDelegate();
}
}
}
You can use call method by like this : Foo.Data2()
public class Foo
{
private static Foo _Instance;
private Foo()
{
}
public static Foo GetInstance()
{
if (_Instance == null)
_Instance = new Foo();
return _Instance;
}
protected void Data1()
{
}
public static void Data2()
{
GetInstance().Data1();
}
}
new Foo();
Foo.StaticMethod();
class Foo
{
private static Foo foo;
public Foo()
{
foo = this;
}
private void PrintHello()
{
Console.WriteLine("Hello");
}
public static void StaticMethod()
{
foo.PrintHello();
}
}
Please I think the response to your question could be :
public class <Classname> {
static method() {
(new <Classname>)->non-static();
}
non-static method(){ ...; }
~<Classname>(){...;}
};
When a data member is declared as static, only one copy of the data is maintained for all objects of the class. A static member has or handles a permanent storage.
for C++ and probably C#, when new operator is used, it allocates memory for a class object, the object constructor is called after the memory is allocated. Thus, as a static member is called preceded by it belonging classname, the same way the non-static member is called. Thus, the use of (new Classname) seems like a call of a member with predefined permanent storage like a static data member.
therefore, this method has an inconvenience: the memory allocated to call the non-static method can't be freed because the access to it is not saved; every time the static method which needs that non-static method is called, the memory is allocated with no access to be freed at the end of it process.
To resolve this inconvenience, the class must have a destructor to free memory allocated after each process. You could also use finalizers.
References
https://learn.microsoft.com/en-us/cpp/cpp/static-members-cpp?view=msvc-170
https://learn.microsoft.com/en-us/cpp/cpp/new-operator-cpp?view=msvc-170
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/finalizers
I hope these details will help you.
Static method never allows a non-static method call directly.
Reason: Static method belongs to its class only, and to nay object or any instance.
So, whenever you try to access any non-static method from static method inside the same class: you will receive:
"An object reference is required for the non-static field, method or property".
Solution: Just declare a reference like:
public class <classname>
{
static method()
{
new <classname>.non-static();
}
non-static method()
{
}
}
Assuming that both data1() and data2() are in the same class, then another alternative is to make data1() static.
private static void data1()
{
}
private static void data2()
{
data1();
}

Categories