Using variable calling another one - c#

So im new at C# and i need to know if what i want to do is possible and how heres what I have,
public static class Sempre
{
public static string Raca = "";
}
// Sempre.Raca - can use like this
Now What I want to do is set a variable like thing = "example", and after this call Sempre but with the variable something like, Sempre.thing, but because it's a variable it would actually be Sempre.example.
Example same use I want in php,
$example = mean;
$_SESSION['name'.$example];
would create $_SESSION [namemean];

You can setup your type with an indexer. http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx. To use the indexer, you are required to have an instance class rather than a static one. If you really need to, you can use the singleton pattern to get "static" behavior.
Here is an example of using an indexer:
public class Sempre
{
private Dictionary<string, string> _values = new Dictionary<string, string>();
public string this[string key]
{
get { return _values[key]; }
set { _values[key] = value; }
}
}
You can use it like this:
Sempre sempre = new Sempre();
sempre["example"] = "my value";
string thing = "example";
Console.WriteLine(sempre[thing]);

Generally speaking you can not do this with objects in C# since the code is precompiled prior to runtime.
If you are specifically looking for an implementation of http session state, like you have in the PHP code example then this could be done. Session State is exposed at System.Web.SessionState.HttpSessionState and can be accessed via concatenated strings like in your example like this.
String example = "mean";
Session["name" + example] = 'bar';
//Session["namemean"] is now set to value of 'bar'

If you're only looking to do string substitution, you can also do something like this:
public class StringConstants
{
public static string YES = "yes";
public static string NO = "no";
}
then elsewhere
public void printmessage(bool value)
{
if (value)
{
Console.writeline (string.Format "I Say {0}", StringConstants.YES);
}
else
{
Console.writeline (string.Format "I Say {0}", StringConstants.NO);
}
}
Documentation on string.Format for insertions and compositions is here

Related

How to set property as one type and get as another?

I have this code:
public class TaskDetails
{
private Dictionary<string, string> _arguments;
public string Arguments
{
get
{
string _tmp = "";
foreach (var _item in _arguments)
{
string _str = _item.Key + ": " + _item.Value + "<br>";
_tmp += String.Join(_str, Environment.NewLine);
}
return _tmp;
}
set { _arguments = value; }
}
}
The idea is very simple: I put value into property in the form I'm comfortable with up the code (i.e. Dictionary), but I get it from property in the form for representation down the code - the string.
But IDE says about set accessor that I cannot implicitly convert type string to Dictionary. Silly IDE, I want to put in Dictionary into Dictionary-type private property.
How, then, should I do it to publicly set property as Dictionary and publicly get this property as string?
The notion of representing a dictionary as a <br> delimited set of plaintext strings is a little unusual and will probably need tweaks at some point in the future (e.g. if you wanted to put the text into div elements to make them valid HTML5, or if you wanted to provide escaping to prevent XSS, or you might want to use CRLF instead of Environment.Newline to match the HTTP protocol). So I'd suggest you encapsulate that idea in a class of its own. This will improve your maintainability.
Then you can give you custom class some implicit conversion operators, and you can write code that automatically converts to/from string or dictionary, allowing you to code it the way you were thinking (even though it's doing something slightly different under the covers).
public class HtmlDictionary //Or some other name
{
private readonly Dictionary<string, string> _arguments;
public HtmlDictionary(Dictionary<string, string> arguments)
{
_arguments = arguments;
}
public override string ToString()
{
string tmp = "";
foreach (var item in arguments)
{
string str = $"{item.Key}: {item.Value}<br>\r\n";
tmp += str;
}
return tmp;
}
public static implicit operator string(HtmlDictionary input) => input.ToString();
public static implicit operator HtmlDictionary(Dictionary<string, string> input) => new HtmlDictionary(input);
}
Now you can do this:
public class TaskDetails
{
public HtmlDictionary Arguments { get; set }
}
var o = new TaskDetails();
o.Arguments = new Dictionary<string,string>();
string s = o.Arguments;
It looks like you are setting a different type than you are getting, but under the covers the compiler is just implicitly converting for you.
P.S. The underscore generally precedes member variables only. It will confuse a lot of people if you put an underscore in front of local variable names too.

Accessing constants using string variable

I'm working on Unity, using C#, and I made up a script that would make my life simpler if I could access constants using string variables.
public class Foo
{
public const string FooConst = "Foo!";
public const string BarConst = "Bar!";
public const string BazConst = "Baz!";
}
// ...inside some method, somewhere else
public string Bar(string constName)
{
// is it possible to do something like this?
// perhaps with reflections?
return Foo.GetConstant(constName);
}
My only solution was to create a method that gets the constant inside a switch. But every time I add a new constant, I have to modify that switch.
Fun fact: I'm a PHP kid that moved into C#. I like it is pretty strict, strong-typed and stuff... but that also makes things unnecessarily complicated.
This uses reflection:
var value = typeof ( Foo ).GetFields().First( f => f.Name == "FooConst" ).GetRawConstantValue();
You could certainly do that using reflection, but IMHO a better option would be to store the constants in a dictionary or some other data structure. Like so:
public static class Foo
{
private static Dictionary<string,string> m_Constants = new Dictionary<string,string>();
static Foo()
{
m_Constants["Foo"] = "Hello";
// etc
}
public static string GetConstant( string key )
{
return m_Constants[key];
}
}
public string Bar( string constName )
{
return Foo.GetConstant( constName );
}
Obviously this is a simplification. And it would throw an exception if you pass a key that doesn't exists etc.
you could try in this way with reflection
var constExample= typeof(Foo).GetFields(BindingFlags.Public | BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.Name==constName).FirstOrFefault();
where constName is the constant that you are looking for
Refere here for documentation about property of FieldInfo.
As you can see I have filtered for IsLiteral = true and IsInitOnly = false
IsLiteral:
Gets a value indicating whether the value is written at compile time
and cannot be changed.
IsInitOnly:
Gets a value indicating whether the field can only be set in the body
of the constructor.
Yes, you have to use Reflection. Like this:
public string Bar(string constName)
{
Type t = typeof(Foo);
return t.GetField(constName).GetValue(null));
}

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

Access property by Index

I need to access a property by an index or something similar. The reason why is explained in this already answered question. That answer uses Linq and I prefer something without that dependency. I have no control over the class.
public class myClass
{
private string s = "some string";
public string S
{
get { return s; }
}
}
class Program
{
static void Main(string[] args)
{
myClass c = new myClass();
// I would like something similar
// or same functionality
string s = c["S"];
}
}
As you have no control over the class you can use extension method and reflection to get property value by name:
static class ObjectExtensions
{
public static TResult Get<TResult>(this object #this, string propertyName)
{
return (TResult)#this.GetType().GetProperty(propertyName).GetValue(#this, null);
}
}
Usage:
class A
{
public string Z
{
get;
set;
}
public int X
{
get;
set;
}
}
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.Z = "aaa";
obj.X = 15;
Console.WriteLine(obj.Get<string>("Z"));
Console.WriteLine(obj.Get<int>("X"));
Console.ReadLine();
}
}
use (EDIT - as per comment):
string s = c.GetType().GetProperty ("S").GetGetMethod().Invoke (c, null).ToString();
It gives you the value of the (public) property named S of the the instance c regardless of the type of c and doesn't use LINQ at all although I must admit that I don't see why LINQ should be a problem...
You can achieve the same thing by using a default property on your class and a collection. Provided that you will always want strings, you could use the Dictionary class as your default property.
Then in the constructor you could intialize myDictionary["s"] = "some string";
You could then use the myClass as a collection, so myClass["s"] would return "some string".
Reflection is usually an indicator that you haven't created an API to do the job you need, if you have the code to modify then I recommend you use the default property.
See this MSDN article:

Does C# support the use of static local variables?

Related: How do I create a static local variable in Java?
Pardon if this is a duplicate; I was pretty sure this would have been asked previously, and I looked but didn't find a dupe.
Is it possible for me to create a static local variable in C#? If so, how?
I have a static private method that is used rarely. the static method uses a Regular Expression, which I would like to initialize once, and only when necessary.
In C, I could do this with a local static variable. Can I do this in C#?
When I try to compile this code:
private static string AppendCopyToFileName(string f)
{
static System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
}
...it gives me an error:
error CS0106: The modifier 'static' is not valid for this item
If there's no local static variable, I suppose I could approximate what I want by creating a tiny new private static class, and inserting both the method and the variable (field) into the class. Like this:
public class MyClass
{
...
private static class Helper
{
private static readonly System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
internal static string AppendCopyToFileName(string f)
{
// use re here...
}
}
// example of using the helper
private static void Foo()
{
if (File.Exists(name))
{
// helper gets JIT'd first time through this code
string newName = Helper.AppendCopyToFileName(name);
}
}
...
}
Thinking about this more, using a helper class like this there would yield a bigger net savings in efficiency, because the Helper class would not be JIT'd or loaded unless necessary. Right?
No, C# does not support this. You can come close with:
private static System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
private static string AppendCopyToFileName(string f)
{
}
The only difference here is the visibility of 're'. It is exposed to the classm not just to the method.
The re variable will be initialized the first time the containing class is used in some way. So keep this in a specialized small class.
Not in C#, only in Visual Basic .NET:
Sub DoSomething()
Static obj As Object
If obj Is Nothing Then obj = New Object
Console.WriteLine(obj.ToString())
End Sub
VB.NET have lot of nice things that C# does not have, thats why I choose VB.NET.
Unfortunately, no. I really loved this possibility in C.
I have an idea what you could do.
Create a class that will provide access to instance-specific values, which will be preserved statically.
Something like this:
class MyStaticInt
{
// Static storage
private static Dictionary <string, int> staticData =
new Dictionary <string, int> ();
private string InstanceId
{
get
{
StackTrace st = new StackTrace ();
StackFrame sf = st.GetFrame (2);
MethodBase mb = sf.GetMethod ();
return mb.DeclaringType.ToString () + "." + mb.Name;
}
}
public int StaticValue
{
get { return staticData[InstanceId]; }
set { staticData[InstanceId] = value; }
}
public MyStaticInt (int initializationValue)
{
if (!staticData.ContainsKey (InstanceId))
staticData.Add (InstanceId, initializationValue);
}
}
Can be used this way...
class Program
{
static void Main (string[] args)
{
// Only one static variable is possible per Namespace.Class.Method scope
MyStaticInt localStaticInt = new MyStaticInt (0);
// Working with it
localStaticInt.StaticValue = 5;
int test = localStaticInt.StaticValue;
}
}
It's not a perfect solution, but an interesting toy.
You can only have one static variable of this type per Namespace.Class.Method scope. Won't work in property methods - they all resolve to the same name - get_InstanceId.
C# doesn't support static local variables. In addition to what has been posted above, here's a 2004 MSDN blog entry on the subject: Why doesn't C# support static method variables?
(Same blog entry in the Microsoft's own archive. The Web Archive preserved the comments. Microsoft archive didn't.)
Why not create a static readonly member on your class and initialize it in a static constructor maybe?
This will give you the same performance benefit - it will only get initialised once.
What about this, since you only want it to be initialized if it's used:
private static System.Text.RegularExpressions.Regex myReg = null;
public static void myMethod()
{
if (myReg == null)
myReg = new Regex("\\(copy (\\d+)\\)$");
}
I developed a static class that deals with this problem in a fairly simple manner:
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public static class StaticLocal<T>
{
static StaticLocal()
{
dictionary = new Dictionary<int, Dictionary<string, Access>>();
}
public class Access
{
public T Value { get; set; }
public Access(T value)
{
Value = value;
}
}
public static Access Init(T value, [CallerFilePath]string callingFile = "",
[CallerMemberName]string callingMethod = "",
[CallerLineNumber]int lineNumber = -1)
{
var secondKey = callingFile + '.' + callingMethod;
if (!dictionary.ContainsKey(lineNumber))
dictionary.Add(lineNumber, new Dictionary<string, Access>());
if (!dictionary[lineNumber].ContainsKey(secondKey))
dictionary[lineNumber].Add(secondKey, new Access(value));
return dictionary[lineNumber][secondKey];
}
private static Dictionary<int, Dictionary<string, Access>> dictionary;
}
It can be implemented within a method like this:
var myVar = StaticLocal<int>.Init(1);
Console.Writeline(++myVar.Value);
On each subsequent call to the method, the value contained in myVar.Value will be the last one it was set to so repeated calls will cause it to output a sequence of natural numbers. The Init() function only sets the value if it has not been previously initialized. Otherwise it just returns a reference to an object containing the value.
It makes use of the [CallerFilePath], [CallerMemberName] and [CallerLineNumber] attributes to track which item in the dictionary is being referred to. This eliminates the possibility of collisions between methods with the same names or calls from the same line numbers.
A few caveats about its usage:
As others have stated, it's worthwhile to consider whether what you're doing really requires the use of static local variables. Their use can sometimes be a sign that your design is flawed and could use some refactoring.
This method of dealing with the problem involves a couple layers of indirection, slowing down the execution of your program. It should only be used if it justifies that cost.
Static local variables can help you to deal with having too many members declared in your class, thus compartmentalizing them where they're used. This should be weighed against the execution time cost but can sometimes be worth it. On the other hand, having so many members being declared within a class may be an indication of design problems worth considering.
Because these values continue to remain in memory after their methods complete execution you must be mindful that using them to store large chunks of memory will prevent garbage-collection until the program completes, thus diminishing your available resources.
This approach is probably overkill for most instances where you would want to use static local variables. Its use of indirection to deal with separate files, methods and lines might be unnecessary for your project, in which case you can simplify it to meet your needs.
Sure. You just have to declare the private static variable outside of the method.
private static readonly System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex( "\\(copy (\\d+)\\)$" );
private static string AppendCopyToFileName( string f )
{
//do stuff.
}
This is effectively what you are doing with the only difference being that "re" has visibility to the entire class as opposed to just the method.
I haven't seen a good generic solution to this yet so I thought I'd come up with my own. I should note however that for the most part(not always) needing static local variables is probably a sign that you should refactor your code for the reasons that have been stated by many people; state is something for the object not a method. I do however like the idea of limiting the scope of variables.
Without further ado:
public class StaticLocalVariable<T>
{
private static Dictionary<int, T> s_GlobalStates = new Dictionary<int, T>();
private int m_StateKey;
public StaticLocalVariable()
{
Initialize(default(T));
}
public StaticLocalVariable( T value )
{
Initialize(value);
}
private void Initialize( T value )
{
m_StateKey = new StackTrace(false).GetFrame(2).GetNativeOffset();
if (!s_GlobalStates.ContainsKey(m_StateKey))
{
s_GlobalStates.Add(m_StateKey, value);
}
}
public T Value
{
set { s_GlobalStates[m_StateKey] = value; }
get { return s_GlobalStates[m_StateKey]; }
}
}
This isn't thread safe of course but it wouldn't take too much work to make it so. It can be used like so:
static void Main( string[] args )
{
Console.WriteLine("First Call:");
Test();
Console.WriteLine("");
Console.WriteLine("Second Call:");
Test();
Console.ReadLine();
}
public static void Test()
{
StaticLocalVariable<int> intTest1 = new StaticLocalVariable<int>(0);
StaticLocalVariable<int> intTest2 = new StaticLocalVariable<int>(1);
StaticLocalVariable<double> doubleTest1 = new StaticLocalVariable<double>(2.1);
StaticLocalVariable<double> doubleTest2 = new StaticLocalVariable<double>();
Console.WriteLine("Values upon entering Method: ");
Console.WriteLine(" intTest1 Value: " + intTest1.Value);
Console.WriteLine(" intTest2 Value: " + intTest2.Value);
Console.WriteLine(" doubleTest1 Value: " + doubleTest1.Value);
Console.WriteLine(" doubleTest2 Value: " + doubleTest2.Value);
++intTest1.Value;
intTest2.Value *= 3;
doubleTest1.Value += 3.14;
doubleTest2.Value += 4.5;
Console.WriteLine("After messing with values: ");
Console.WriteLine(" intTest1 Value: " + intTest1.Value);
Console.WriteLine(" intTest1 Value: " + intTest2.Value);
Console.WriteLine(" doubleTest1 Value: " + doubleTest1.Value);
Console.WriteLine(" doubleTest2 Value: " + doubleTest2.Value);
}
// Output:
// First Call:
// Values upon entering Method:
// intTest1 Value: 0
// intTest2 Value: 1
// doubleTest1 Value: 2.1
// doubleTest2 Value: 0
// After messing with values:
// intTest1 Value: 1
// intTest1 Value: 3
// doubleTest1 Value: 5.24
// doubleTest2 Value: 4.5
// Second Call:
// Values upon entering Method:
// intTest1 Value: 1
// intTest2 Value: 3
// doubleTest1 Value: 5.24
// doubleTest2 Value: 4.5
// After messing with values:
// intTest1 Value: 2
// intTest1 Value: 9
// doubleTest1 Value: 8.38
// doubleTest2 Value: 9
Along the lines of Henk's and BarretJ's answer, I think you can avoid the initialization cost and come even closer by using a property,
private Regex myReg = null;
private Regex MyReg
{
get {
if (myReg == null)
myReg = new Regex("\\(copy (\\d+)\\)$");
return myReg;
}
}
Then just use MyReg (note the uppercase 'M' in MyReg) everywhere in your code. The nice thing about this solution is that (although the getter is a function call under the hood) the semantics of properties means that you get to write code as if MyReg was a variable.
The above is how I setup "runtime constants" that require a one-time initialization at runtime.
I do the same thing using nullable types, too. For example,
private bool? _BoolVar = null;
private bool BoolVar
{
get {
if (_BoolVar.HasValue)
return (bool)_BoolVar;
_BoolVar = /* your initialization code goes here */;
return (bool)_BoolVar;
}
}
Then just use BoolVar like a regular normal bool in your code. I don't use internal _BoolVar (the backing store for the BoolVar property) because I just don't need to, remember this is like a runtime constant, so there is no setter. However, if I needed to change the value of the runtime constant for some reason, I'd do that directly on the nullable variable _BoolVar.
The initialization could be pretty involved. But it's only executed one time and only on the first access of the property. And you have the choice of forcing the re-initialization of the runtime constant value by setting _BoolVar back to null.
Nesting the related members in an inner class as you have shown in question is the cleanest most probably. You need not push your parent method into inner class if the static variable can somehow get the caller info.
public class MyClass
{
...
class Helper
{
static Regex re = new Regex("\\(copy (\\d+)\\)$");
string caller;
internal Helper([CallerMemberName] string caller = null)
{
this.caller = caller;
}
internal Regex Re
{
//can avoid hard coding
get
{
return caller == "AppendCopyToFileName" ? re : null;
}
set
{
if (caller == "AppendCopyToFileName")
re = value;
}
}
}
private static string AppendCopyToFileName(string f)
{
var re = new Helper().Re; //get
new Helper().Re = ...; //set
}
private static void Foo()
{
var re = new Helper().Re; //gets null
new Helper().Re = ...; //set makes no difference
}
}
You can avoid hard coding of method names in the property using some expression tree tricks.
You can avoid the helper constructor and make the property static, but you need to get the caller info inside the property, via using StackTrace.
Lastly, there is always const possible inside a method, but then one, it's not variable, two, only compile time constants are allowed. Just stating.
Three years later...
You can approximate it with a captured local variable.
class MyNose
{
private static void Main()
{
var myNose= new MyNose();
var nosePicker = myNose.CreatePicker();
var x = nosePicker();
var y = nosePicker();
var z = nosePicker();
}
public Func<int> CreatePicker()
{
int boog = 0;
return () => boog++;
}
}
I was reading this post recently, because I was courious to know, if the mentioned Visual Basic feature (or C feature, which I wasn't aware) would exist in C# as well.
However, I took some time to put together a solution of all the pre-posts. Some word in advance:
It's not thread safe (but you can bulid it that way)
Because of the use of StackFrame it's painfully slow (as statet in previous post)
The solution approach includes not just static local variables, but also non-static variables with proper memory clean-up
It's bricolage
The tool is this class:
public static class Persistent<T> where T : struct
{
static readonly Dictionary<int, T[]> staticValues;
public static ref T Static(T value)
{
var stackFrameOffset = new StackFrame(1, false).GetNativeOffset();
if (!staticValues.ContainsKey(stackFrameOffset))
staticValues.Add(stackFrameOffset, new T[] { value });
return ref staticValues[stackFrameOffset][0];
}
static readonly ConditionalWeakTable<object, Dictionary<int, T[]>>
nonStaticValues;
public static ref T Local(T value, object callerInstance)
{
var stackFrameOffset = new StackFrame(1, false).GetNativeOffset();
if (!nonStaticValues.TryGetValue(callerInstance, out var storage))
{
storage = new Dictionary<int, T[]>
{
{ stackFrameOffset, new T[] {value} }
};
nonStaticValues.Add(callerInstance, storage);
}
else if (!storage.ContainsKey(stackFrameOffset))
{
storage.Add(stackFrameOffset, new T[] { value });
}
return ref storage[stackFrameOffset][0];
}
static Persistent()
{
staticValues = new Dictionary<int, T[]>();
nonStaticValues = new ConditionalWeakTable<object,
Dictionary<int, T[]>>();
}
}
And the use is like that:
public void Method1()
{
ref int myInt = ref Persistent<int>.Local(0, this);
myInt++;
Console.WriteLine($"myInt is now {myInt}");
}
The same applies for Persistent.Static(77) instead of Local where one is for static values while the other method is vor non-static ones...
If you like to read my considerations about, look here:
https://csatluegisdorf.blogspot.com/2021/11/persistent-variables-for-method-scope.html
Here is sort of a hackish way to accomplish what you're trying to do. Turn MyMethod into an Action that creates a closure on x. The variable x will only be visible to the innermost delegate, and behaves like a static variable. If anyone has any suggestions for improving this pattern let me know.
public static readonly Func<string, string> MyMethod = new Func<Func<string, string>>(delegate ()
{
var x = new Regex("abc", RegexOptions.IgnoreCase); //this Regex will be "static"
return delegate (string input) { return x.Replace(input, "123"); };
}).Invoke();
//example usage:
public void Init()
{
Console.WriteLine(MyMethod("abc")); //console will output "123"
}

Categories