Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a static class called Constants.
public static class Constants
{
public static string sampleString= "";
public static List<int> sampleList= new List<int> {1,2,3};
}
If I call my static list outside:
Constants.sampleList it gives me a null exception but Constants.sampleString can be called with no problem.
Am I missing something here?
Not sure if this is the same case as ours but we have a class that access the key from the config
string sampleString = WebConfigurationManager.AppSettings["SampleString"]
Sample string was deleted from our web.config due to some merging issues. Error for null pointer happens when you access any of the variables in the class bellow the variable.
Adding the key in the config fixed the issue.
When I run this code:
void Main()
{
Console.WriteLine(Constants.sampleList.Contains(1));
}
public static class Constants
{
public static string sampleString= "";
public static List<int> sampleList= new List<int> {1,2,3};
}
I get True on the Console. You need to provide the code which demonstrates the issue you're facing.
If you add readonly keyword to your method. The method can only be instantiated inside constructor or at the property declaration phase.
public static readonly List<int> sampleList= new List<int> {1,2,3};
If you ever try to reinitialize or make new assignment to sampleList, C# compiler will give you compiler error.
Yet better to use Property
public static readonly List<int> SampleList {get; set;} = new List<int> {1,2,3};
There are no miracles, and if sampleList is null (and you have exception thrown) then you asign null to it somewhere.
Try not to expose public fields which makes Constants vulnerable:
public static class Constants
{
public static string sampleString = "";
public static List<int> sampleList = new List<int> {1,2,3};
}
...
Constants.sampleList = null; // We can easly assign null
...
Constants.sampleList.Add(123); // <- And have an unxpected exception
But either turn them into properties:
public static class Constants
{
private static string s_SampleString = "";
private static List<int> s_SampleList = new List<int> {1,2,3};
public static string sampleString {
get {return s_SampleString;}
set {s_SampleString = value ?? "";}
}
public static List<int> sampleList {
get {return s_SampleList;}
// I doubt you actually want set here
set {s_SampleList = value ?? new List<int>();}
}
}
Or, at least, mark the field(s) as readonly (you can assign them once only):
public static class Constants
{
private static string s_SampleString = "";
public static string sampleString {
get {return s_SampleString;}
set {s_SampleString = value ?? "";}
}
// Manipulate with me, but not reassign
public static readonly List<int> sampleList = new List<int> {1,2,3};
}
In either case you still can manipulate with the list:
Constants.sampleList.Add(4);
Constants.sampleList.RemoveAt(0);
But you are protected from assigning null to the list: either empty list will be assigned (code with property) or you'll have compile time error (code with readonly)
In my case, I was defining a private static readonly Dictionary<byte, string> inside a struct to hold predefined constants. This normally would work fine, however I also had defined a MinValue within my struct to represent the minimum value of a piece of data. When done this way the static dictionary was uninitialized unless defined above the static MinValue property. I'm probably asking a little too much of the compiler and should restructure it instead.
It was hard to diagnose in a large struct as I didn't expect that behavior with C#. Example to reproduce:
public struct MyStruct
{
public string Str;
public static readonly MyStruct MinValue = new MyStruct(0);
public MyStruct(byte val)
{
Str = _predefinedValues[val]; // null reference exception
}
private static readonly Dictionary<byte, string> _predefinedValues = new Dictionary<byte, string>()
{
{0x00, "test 1"},
{0x01, "test 2"},
{0x02, "test 3"},
};
}
The solution here is twofold:
to not call any constructors on the struct and explicitly set each field without accessing _predefinedValues list.
Alternatively, moving the list up above the MinValue field declaration actually does fix it as well (strange right?)
I suspect something weird happens on the stack when trying to allocate this and it's probably a weird thing to do.
Related
I switched the Value Analysis Mode in Rider to Pessimistic to highlight every "Possible NullReferenceException" and in the example below, I have a warning on the "Languages[0]" part and I don't understand why since I initialize my collection right after declaring it.
It should not be null then.
I just tested on an empty project and I have the same warning.
using System.Collections.Generic;
namespace ClassLibrary1
{
public class Class1
{
public static string Current => Languages[0];
public static readonly List<string> Languages = new List<string>
{
"en"
};
}
}
Is it a mistake made by ReSharper or did I missed something ?
Thanks.
I think static properties are evaluated in order of appearance. Try to flip them in order to have first "Languages" and then "Current".
Try this:
public static class Program
{
public static readonly string Foo = Current;
public static string Current => Languages[0];
public static readonly List<string> Languages = new List<string>
{
"en"
};
public static void Main()
{
Console.WriteLine(Foo);
}
}
SharpLab
Static members are initialized in the order they're declared. Foo is initialized before Languages is assigned, and so you see a NullReferenceException.
I guess that Resharper's being very pessimistic here, and only considering Current in isolation, regardless of whether there's actually another static member that might access it before Languages is initialised.
You could also have something diabolical like this, where the construction of Languages causes something to access Program.Current:
public static class Program
{
public static string Current => Languages[0].Value;
public static readonly List<Language> Languages = new List<Language>() { new Language() };
public static void Main()
{
Console.WriteLine(Current);
}
}
public class Language
{
public string Value { get; } = Program.Current;
}
(It's a silly example, but it shows that it's perhaps harder for Resharper to prove that nothing accesses Program.Current before Program's type initializer has finished running, than you might expect).
I am trying to find the right structure to store some global variables. I basically have 2 set of similar variables grouped under Option A/B. The choice between A and B set is done from the app.config. The data have the following structure:
[OptionA][VAR1] = "myValue1OptionA"
[OptionA][VAR2] = {'a','b','c'}
[OptionA][VAR3] = 3
[OptionB][VAR1] = "myValue1OptionB"
[OptionB][VAR2] = {'a','b','c','d','e'}
[OptionB][VAR3] = 120
I can use a dictionary with a tuple as index but it is a bit heavy in term of casting when using the variables:
private static GlobalVar<Tuple<string, string>, var> instances =
new Dictionary<Tuple<string, string>, var>(){
{Tuple.Create("OptionA","VAR1"), "myValue1OptionA"},
{Tuple.Create("OptionA","VAR2"), {'a','b','c'}},
{Tuple.Create("OptionA","VAR3"), 3},
{Tuple.Create("OptionB","VAR1"), "myValue1OptionB"},
{Tuple.Create("OptionB","VAR2"), {'a','b','c','d','e'}},
{Tuple.Create("OptionB","VAR3"), 120},
};
I thought of 2 statics classes but retrieving the values and casting is also a bit cumbersome.
static class GlobalVarOptionA
{
static string VAR1 = "myValue1OptionA";
static char[] VAR2 = {'a','b','c'};
static int VAR3 = 3;
}
static class GlobalVarOptionB
{
static string VAR1 = "myValue1OptionB";
static char[] VAR2 = {'a','b','c','d','e'};
static int VAR3 = 120;
}
Usage should be something like:
Type t = Type.GetType("GlobalVarOptionB");
var pinfo = t.GetProperties(BindingFlags.Static | BindingFlags.Public);
Any help/advice will be appreciated.
If the choice between A and B comes form the app.config file, this means it is done once at startup of your program.
So you should create/initialize just one of these structures in memory after the app.config is read.
Because it is structured data (as opposed to a string/string list) I'd use a static class as you did with static class GlobalVarOption
For me better approach will be one static class with properties where you can internally check which option to return
or use singleton pattern
class GlobalVariables
{
public static GlobalVariables Instance = new GlobalVariables();
public readonly string VAR1;
public readonly char[] VAR2;
public readonly int VAR3;
private GlobalVariables()
{
// Set values based on the App.config options
}
}
Using
GlobalVariables.Instance.VAR1
I have two .cs files (Hex2Bin.cs and Program.cs) and I want to pass the variable end_addr from Program.cs to Hex2Bin.cs
My code in Program.cs:
class Program
{
enum to_exit {
exit_ok = 0,
exit_invalid_args,
exit_to_few_args,
exit_invalid_input_file,
exit_invalid_args_file,
exit_permission_denied,
exit_unexpected_eof
};
// class value holders
static String args_file_name = "";
static String in_u1_name = "";
static String in_u22_name = "";
static String out_name = "";
static short end_addr = 0x0000; // 4-digit Hexadecimal end address
static Byte[] version_code = { 0, 0, 0, 0 }; // 3 bytes version, 1 for extra info
}
Is there anyway I could do this? I know how to do it in c, but I'm very new to c#. Thanks.
C# doesn't work like C with respect to static variables. You can make the variable end_addr available outside the Program class by making it a public field. By default, fields are private.
public static end_addr = 0x0000;
And then it can be accessed like so:
var x = Program.end_addr;
However, I would recommend that you spend a little more time familiarizing yourself with C# idioms and conventions. It seems like your still thinking about C# in terms of C, and they are very different.
if you declare the variable like this:
public static short end_addr = 0x0000;
then from another class you can use it like this:
Program.end_addr
but don't do this, is not object oriented!
if your class Hex2Bin is used/invoked by the Main method of Program class, you should be able to pass your variables as input parameters of the methods you call or set them as properties of the classes/objects you use...
It's enough to mark end_addr as public like so
public static short end_addr = 0x0000;
Then you can access it from anywhere like this
Program.end_addr
It's a better practice though to use properties rather than fields for exposing data.
// Property
public static short end_addr { get; private set; }
// Constructor
public Program()
{
// Initialize property value.
end_addr = 0x0000;
}
You're talking about 'files' but what you really want to do is to pass data from your program's entry point (Program.cs) to a an object of a class (or method of static class) that will process the data, am I right?
If so, this should be pretty simple. You either have to modify your Program.cs and create an instance of the class (the one from Hex2Bin.cs) like this
...
Hex2Bin hex2bin = new Hex2Bin( end_addr );
...
I assume that the Hex2Bin is as follows:
public class Hex2Bin
{
private short endAddress;
public Hex2Bin( short endAddress )
{
this.endAddress = endAddress;
}
}
this will allow you to use the value of end_addr from Program.cs
Another approach is to pass it directly to the method that will make use of it:
Hex2Bin.Method(end_addr);
and in the Hex2Bin file:
public static void Method(short endAddress)
{
//... do the work here
}
Given your background in C, I think you may be mixing runtime with compile time issues.
However, in Hex2Bin.cs, you can create a static method that updates a static variable.
class Hex2Bin
{
static short end_addr = 0x0000;
static void updateEndAddr(short endAddr)
{
end_addr = endAddr;
}
}
This is my first time posting on Stack Overflow, so hopefully I did everything right and you guys can help.
I'm wondering if in C# there's a way to access a static variable belonging to a class, when given only the type of the class. For example:
public class Foo
{
public static int bar = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
int tempInt = ??? // Get the value of the variable "bar" from "Foo"
Debug.WriteLine("Bar is currently :" + tempInt);
}
}
// I didn't run this code through a compiler, but its simple enough
// that hopefully you should get the idea...
It's hard to describe the context of needing to know this, but I'm making a game in XNA and I'm trying to use reference counting to reduce the complexity of the design. I have objects in the game and power-ups that can apply an effect them (that stays on the objects). Power-ups can die but their effects can still linger on the objects, and I need to keep track of if any effects from a power-up are still lingering on objects (thus, reference counting). I plan to make a "PowerUpEffect" class (for each type of power-up) with a static integer saving the number of objects still affected by it, but the design of the rest of the game doesn't work well with passing the PowerUpEffect all the way down to the object for it to call a method of the PowerUpEffect class.
I'm hoping to pass only the PowerUpEffect's type (using something like "typeOf()") and use that type to reference static variables belonging to those types, but I have no idea how to do it or if it's even possible.
I'd be glad to even find work-arounds that don't answer this questions directly but solve the problem in a simple and elegant design. =)
Help! (and thanks!)
If you only have the Type handle, you can do this:
var prop = givenType.GetProperty("bar");
var value = prop.GetValue(null);
I would use a Dictionary instead, which are probably the most concise way of mapping one set of values to another. If you are associating int values with Types, then do something like:
public static readonly Dictionary<Type, int> sTypeValues =
new Dictionary<Type, int>
{
{ typeof(Type1), 5 },
{ typeof(Type2), 10 },
{ typeof(Type3), 2 },
{ typeof(Type4), 3 },
{ typeof(Type5), -7 }
};
your function then becomes:
public void myFunc(Type givenType)
{
int tempInt = sTypeValues[givenType];
Debug.WriteLine("Bar is currently :" + tempInt);
}
int tempInt = (int) givenType.GetField("bar").GetValue(null);
Okay, so you have a collection of powerups, and you want to have an integer associated with each of those powerups. Rather than having a lot of classes, each with a static integer, you can have a single static collection which holds onto all of the powerups and their associated integer values.
public static class MyPowerupInfo
{
public static Dictionary<PowerUp, int> PowerUps {get; private set;}
static MyPowerupInfo
{
PowerUps = new Dictionary<PowerUp, int>();
PowerUps.Add(*some power up object goes here*, 0);
//TODO add other power ups
}
}
Then to use it you can do something like:
int powerupCount = MyPowerupInfo.PowerUps[wickedAwesomePowerup];
or:
public static void IncrementPowerup(Powerup powerup)
{
MyPowerupInfo.PowerUps[powerup] = MyPowerupInfo.PowerUps[powerup]+1;
}
If am getting you correc, this might give you some idea:
using System;
using System.Reflection;
public class RStatic
{
private static int SomeNumber {get; set;}
public static object SomeReference {get; set;}
static RStatic()
{
SomeReference = new object();
Console.WriteLine(SomeReference.GetHashCode());
}
}
public class Program
{
public static void Main()
{
var rs = new RStatic();
var pi = rs.GetType().GetProperty("SomeReference", BindingFlags.Static | BindingFlags.Public); // i have used GetProperty in my case
Console.WriteLine(pi.GetValue(rs, null).GetHashCode());
}
}
Are you assuming if the name of the field you're trying to access (for example, for the class "foo", the field "bar") is a different field based on the Type parameter?
If the name of the field is known based on a finite number of allowable types, you should be able to determine it with a switch statement. For example:
public class Foo
{
public static int bar = 0;
}
public class Baz
{
public static int bing = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
switch (givenType.ToString())
{
case "Foo":
Debug.WriteLine("Bar is currently :" + Foo.bar);
break;
case "Baz":
Debug.WriteLine("Bing is currently :" + Baz.bing);
break;
}
}
}
I need help about array of structs initiliazation. In a code something like below, how we can accomplish the initiliazation defined in comment ??
class structExample
{
struct state{
int previousState;
int currentState;
}
static state[] durum;
public static void main(String[] args)
{
durum = new state[5];
// how we can assign new value to durum[0].previousState = 0; doesn't work ??
}
}
}
Thanks..
The default accessibility for members in C# is private which is why the assignment statement is failing. You need to make the fields accessible by having adding internal or public to them.
struct state{
internal int previousState;
internal int currentState;
}
durum = new state[5]; -> creates only the array for 5 elements.
You need to initialize every element inside the array.