How can i use variable value as variable name in other script? - c#

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);

Related

How to share constants in c#

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);

Dot notation for class member access

I've got the following code:
public class Random
{
public string Name { get; set; }
public bool IsRunning()
{
var running = true;
return running;
}
}
public class Main
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
which all exists in the same .cs file in the same namespace. Any time I've created a new project before I've never had to set up anything to use dot notation to access member attributes or methods, but this is saying that I can't use newObject. ANYTHING, and also that "var" is not valid for a keyword. It's a windows forms application like I normally use, but I'm drawing blanks here as why I can't do all these things that I normally use many times in my other programs. What am I missing here?
You're trying to write code directly within the class declaration. A class declaration can only directly contain member declarations. It can't contain arbitrary statements such as newObject.Name = "Johnny" nor can it use var, which is only applicable to local variables. If you put the code in a method, it should be absolutely fine. For example:
public class Main
{
public void DoSomething()
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}
As an aside, I'd strongly recommend against naming your own class Random given that that's also the name of a class within the System namespace.
You cannot use var or assign values to some other object within a class member definition.
You code in public class Main is not within a method.
I guess what you were trying to do is writing a Console app and that needs a
public static void Main()
method
so change your class to e.g.
class Program
{
static void Main(string[] args)
{
Random newObject = new Random();
newObject.Name = "Johnny";
var result = newObject.IsRunning();
}
}

How to read the attributes of a class with c#?

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);
}

Following the DRY principle in ASP.NET

I have just recently got involved in a classic ASP.NET project which contains lots of storing and reading values from the session and query strings. This could look something like the following:
Session["someKey"]=someValue;
And somewhere else in the code the value in the session is read. Clearly this violates the DRY principle since you'll have the literal string key spread out all over the code. One way to avoid this could be to store all keys as constants that could be referenced everywhere there is a need to read and write to the session. But I'm not sure that's the best way to do it. How would you recommend I best handle this so that I don't violate the DRY principle?
Create a separate public class where you can define your constants, e.g
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
and then anywhere in your code you can access session variables like this:
Session[SessionVars.SOME_KEY]=someValue;
This way you can get IntelliSence and other bells and whistles.
I think you're reading too much into DRY. I pertains more to things that could be wrapped up in a function. I.e. instead of repeating the same fives lines all over the place wrap those 5 lines in a function and call the function everywhere you need it.
What you have as an example is just setting a value in a dictionary (the session object in this case), and that is the simplest way to store and retrieve objects in it.
I can't remember for the life of me where I humbly re-purposed this code from, but it's pretty nice:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
The idea behind it two fold. The type created should be the only type you need. It's basically a big strongly-typed wrapper. So you have some object you want to keep extending information in:
public class MyClass
{
public MyClass()
public string Blah1 { get; set; }
}
Then down the road you extend MyClass and you don't want to have to remember all the Key Values, store them in AppSettings or Const variables in Static Classes. You simply define what you want to store:
public class MyClassSession : SessionBase<MyClass>
{
}
And anywhere in your program you simply use the class.
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}
Optionally you could place the access to this session object in a base page and wrap it in a property:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
Here you are repeating the myKey string but it is encapsulated into the property. If you want to go to the extreme of avoiding this, create a constant with the key and replace the string.

C# - How to access a static class variable given only the class type?

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;
}
}
}

Categories

Resources