I would like to store static variable in single class and use it in different classes.
What is the best practice in C#?
JavaScript example.
Just for example. I am looking for something like this:
I have single file MyStaticDataObject.js with one or more static variables.
const MyStaticDataObject = {
someKey: someValue,
anotherKey: anotherValue,
//...
}
export { MyStaticDataObject };
and I can use them in any other file:
import { MyStaticDataObject } from "./MyStaticDataObject.js";
// ... somewhere in code
console.log(`Value of someKey:`, MyStaticDataObject["someKey"]);
namespace nm1 {
internal class MyStaticDataObject {
public const string Key1 = "Value1";
public const string Key2 = "Value2";
}
}
In other classes (outside the namespace), reference the namespace using nm1; and use it. Otherwise they can be used directly without the using
using nm1;
internal class TestClass
{
private string Key1 = MyStaticDataObject.Key1;
}
Maybe late.
But this is a better way - if you need use these constants value frequently.
Declare a class with some constants.
public class ConstantsClass
{
public const string ConstName1 = "ConstValue1";
public const string ConstName2 = "ConstValue2";
public const string ConstName3 = "ConstValue3";
}
Using this class in static in code file you want. (C# 6.0 feature)
using static ConstantsClass;
namespace YourNamespace
{...
Use the constanst in the way same as it declared in local.
CallMethod(ConstName1);
Related
I came from C/C++, and used alot things like #define OBJ_STATE_INPROCESS 2, so that when coding actual logic you can have state = OBJ_STATE_INPROCESS;, and what it does become more obvious than state = 2;, which makes the code easier to maintain.
I wonder if there is some trick like this in C#
Though technically a different concept, in C# you can use contants and enums to avoid "magic numbers", e.g.
public static class Constants
{
public const string MyConst = "ThisIsMyConst";
}
public enum MyEnum
{
MyEnumValue1,
MyEnumValue2,
}
// Usage
var value = MyEnum.MyEnumValue2;
You can accomplish that using constant properties, for example:
static class Constants
{
public const int OBJ_STATE_INPROCESS = 2
}
class Program
{
static void Main()
{
Console.WriteLine(Constants.OBJ_STATE_INPROCESS ); //prints 2
}
}
I have a unity project with a config file (for anim names)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Anims{
public const string anim1= "NameOf anim1";
public const string anim2= "NameOf anim2";
public const string anim3= "NameOf anim3";
...
}
public enum animNames { anim1, anim2,anim3...}
and in another script I want to activate animation using
public animNames name_Of_The_Anim_I_Want_To_Activate;
my issue is to convert name_Of_The_Anim_I_Want_To_Activate.ToString() into the actual animation name
which tool can i use to turn name_Of_The_Anim_I_Want_To_Activate = anim1 into "NameOf anim1";
I want to go through the enum, since there are several buttons each triggering another anim
1. I don't wanna use inheritance or multiple scripts
2. I wanna try a more elegant way than a switch statement. this is why I cant the enum to be able to reach the variable name.
Edit:
Eventually i dumped the "Static config file" idea for a monobehaviour manager
then i could have (static/const or not)
public string anim1= "name1";
public string anim2 = "name2";
public enum CompAnim
{
Company1,
Company2,
}
and use
public string CompanyAnim(CompAnim comp)
{
string toRun =
this.GetType().GetField(comp.ToString()).GetValue(this).ToString();
return toRun;
}
thanks to Camile for the elegant solution, that's exactly what I was looking for.
Assuming that in Anims you have:
public string anim1 = "someAnimation";
In the script where you store the actual animation:
public string someAnimation = "theActualAnimationName";
...
string toRun = this.GetType().GetField(someAnimNamesEnumValue.ToString()).GetValue(this);
This will assign "theActualAnimationName" to the variable toRun
If you store the animations as Animation objects rather than strings, you can use those directly with the above method too.
Edit:
Additionally you might want to look into what reflection is (this is what the code is doing)
You have to just add reference of Anims class in another script and than access variables of Anims. If you have not Static class and static members.
In your case you just acess Anims Properties like:
var name_Of_The_Anim_I_Want_To_Activate = Anims.anim1;
This is why because you have static class and static member, so you have not need to create instance/object of a class to access variable of Anims class.
Try to Add an helper function similar to this:
public static string GetStringValue(animNames enumTarget)
{
switch (enumTarget)
{
case animNames.anim1:
return Anims.anim1;
break;
case animNames.anim2:
return Anims.anim2;
break;
case animNames.anim3:
return Anims.anim3;
break;
default:
return "Wrong Enum Value Sent!!";
}
}
Update
In case you can use Dictionary<string,string> then you could do this:
using System.Collections.Generic;
using System.Linq;
public static Dictionary<string, string> _AnimNames = new Dictionary<string, string>();
register the entries like that
_AnimNames.Add("anim1", "NameOf anim1");
_AnimNames.Add("anim2", "NameOf anim2");
_AnimNames.Add("anim3", "NameOf anim3");
Create an helper method like that:
public static string GetStringValue(animNames enumTarget)
{
var key = System.Enum.GetName(typeof(animNames), enumTarget);
var nameEntry = _AnimNames.FirstOrDefault(x => x.Key == key);
var nameValue = nameEntry.Value;
return nameValue;
}
so finally you can use it like this:
name_Of_The_Anim_I_Want_To_Activate = animNames.anim2;
var name = GetStringValue(name_Of_The_Anim_I_Want_To_Activate);
I have a class where I define one constant from another class would read these constants or the content of attributes and properties of the class . Something like read the metadata of the class.
something like this:
namespace Ventanas._01Generales
{
class Gral_Constantes
{
public class Cat_Productos
{
public const String Tabla_Productos = "Cat_Productos";
public const String Campo_Producto_ID = "Producto_ID";
}
public class Cat_Grupos_Productos
{
public const String Tabla_Grupos_Productos = "Cat_Grupos_Productos";
public const String Campo_Grupo_Producto_ID = "Grupo_Producto_ID";
}
}
}
in other class for example some like this
namespace Ventanas._01Generales
{
class Pinta_Ventana
{
public void Crea_Insert()
{
foreach(Properties p in Cat_Producto.Properties)
{
miControl.Text = p.value; //show "Cat_Grupos_Productos"
miControl.Name = p.value; //show Tabla_Grupos_Productos
}
}
}
}
You need Type.GetProperties (MSDN) This code will work:
foreach (PropertyInfo p in typeof(Cat_Producto).GetProperties())
{
...
}
Now a few caveats:
You are using reflection which is really slow, and the fact that you are using it indicates you are likely doing something terribly wrong.
If you output the way your sample code does, only the last property's information will be visible, since you never let the UI update.
Your code doesn't actually have properties, they have const fields, so this code wouldn't return any of them. Make them properties for this method to work. You can use Type.GetFields if you want the fields version.
It looks like you want to use the System.Reflection namespace. If you are interested in getting the names of the public const strings, you will need to use MemberInfo. This should get you started:
MemberInfo[] members = typeof(MyClass).GetMembers();
foreach(MemberInfo m in members)
{
//do something with m.Name
Console.WriteLine(m.Name);
}
Is it possible to initializing value of a constant value using method of another class
namespace ConsoleApplication1
{
class Program
{
const int gravit = haha.habc();//something like this
static void Main(string[] args)
{
some codes.....
}
public class haha
{
int gar = 1;
public int habc()
{
int sa = 1;
return sa;
}
}
}
}
For example like the codes above(FYI with this code I am getting Expression being assigned to ... must be constant), if not is there other method to do something similar to this.
No, that's not possible, you could use readonly field instead because constant values should be known at compile-time:
private static readonly int gravit = haha.habc();//something like this
NOTE: the habc method should be static if you want to call it that way.
Constants are values which should be known at compile time and do not change. So the ReadOnly is the option you should go with.
private readonly int gravit = haha.habc();
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;
}
}