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"
}
Related
This application is supposed to be a sort of demo of how blockchain works. I have a block chain class and a block class and the program class is main. In the blockchain class I am creating an initial block called the gensis block in the createGenesisBlock() method. In the constructor of my blockchain class I am calling the createGenesisBlock() method and inserting the object into my linked-list which is called chain. The problem I have is when the object is added to the linked-list in my blockchain class I cannot access the object or the methods. What I am trying to accomplish is to use my getLatestBlock() method in the blockchain class to retrieve the value of hash of the last object that was put into chain. Thus being able to call my addBlock method in blockchain setting the value of previousHash equal to the value of hash of the object in the linked-list
namespace BlockChainProject
{
class Program
{
static void Main(string[] args)
{
Blockchain blockChain = new Blockchain();
blockChain.addBlock();
blockChain.display();
Console.ReadKey();
}
}
}
namespace BlockChainProject
{
class Block
{
private int index;
private string timeStamp;
private string data;
private string previousHash;
private string hash;
public Block(int index, string timeStamp, string data, string previousHash) {
this.index = index;
this.timeStamp = timeStamp;
this.data = data;
this.previousHash = previousHash;
this.hash = this.calculateHash();
}
public string calculateHash() {
SHA256Managed hashString = new SHA256Managed();
byte[] dataArray = hashString.ComputeHash(Encoding.UTF8.GetBytes(index.ToString() + previousHash + timeStamp + data));
StringBuilder stringBuilder = new StringBuilder();
foreach (byte x in dataArray)
{
stringBuilder.AppendFormat("{0:X2}", x);
}
string hashed = stringBuilder.ToString();
return hashed;
}
public string getHash() {
return hash;
}
}
}
namespace BlockChainProject
{
class Blockchain
{
LinkedList<object> chain;
private int index = 0;
private string time = DateTime.Now.ToString();
public Blockchain(){
chain = new LinkedList<object>();
chain.AddLast(createGenesisBlock());
}
private object createGenesisBlock() {
index++;
return new Block(index, time, "Genesis Block", "0"); ;
}
public object getLatestBlock() {
return chain.Last.Value;
}
public void addBlock() {
string data = Console.ReadLine();
//string previousHash = <The hash of linked lists last object here>;
chain.AddLast(new Block(index, time, data, previousHash));
index++;
}
public void display() {
foreach (var item in chain)
{
Console.WriteLine(item);
}
}
}
}
I quickly ran your code and I think that I have figured out your problem. You need to do a find and replace on "object" and replace it with "Block" or alternatively you need to cast the objects that are being returned from the getLast function to "Block".
An example of the changes will look like so:
LinkedList<Block> chain;
...
public Block getLatestBlock() {
return chain.Last.Value;
}
This is some examples of the changes to be made to the Blockchain class there may be others but I can't remember.
Now when you call the display function you have access to the functions and methods of each of the Block class instances in the linked list, like so:
public void display()
{
foreach (var item in chain)
{
Console.WriteLine(item.getHash());
}
}
This will now print a list of the hashes provided that you changed all of the returns, types and instances where you used object in the linked list, to Block.
The reason for this is if you create a linkedlist of generic "object"s then at compile time C# has no idea what might be in the linked lists. It could be Blocks or it could be Bananas, so it doesn't know what functions and methods each object will have available to call. So to let C# know we have to either cast it using "as Block" after we get the item from the list or in your case just set the type of all values in the linked like to "Block" as by the looks of your program you aren't going to have generic entries to the list.
Hopefully this answers your question. If not let me know.
When you specify your chain as
LinkedList<object> chain
You are telling the compiler that the chain variable is a linked list that contains an object class, or any descendent of object.
The following code is therefore legal by your definition of chain
chain.Add("Hi there!");
chain.Add(new Dictionary<int, decimal>());
chain.Add(new Giraffe());
chain.Add(42);
You cannot call calculateHash() because unfortunately, our string, Dictionary, Giraffe and int classes wouldn't know what to do with such a method call.
Instead, chain should be declared as
LinkedList<Block> chain;
This means that chain can only contain elements that are of type Block (or a descendent class of Block).
Whilst the calls to these methods are not shown in code, you will need to then change the createGenesisBlock() and getLatestBlock() methods to return Block rather than object, because you are not allowed to add just any object to your linked list anymore, it must be a Block.
Okay, so I have a couple of questions. Let me first explain what I have to do. I made this code first, but without the constructor and the two methods had static in their declaration. Now I want to add a constructor that I was provided and I have to make it's instance in the main method, and afterwards provide it with some random values. I also need to call the two methods via an instance in the Main method. At the end, after compiling, it's supposed to say "Hello World!" and "81" So here come the questions:
Are the variables in the constructor supposed to be the named the same as the ones in the methods?
How do I create an instance of the constructor in the main method?
How do I give it some random values?
How do I call the two methods via their instances?
The code:
namespace CalculatorA
{
class Calculator
{
public string WriteText(string parametar1)
{
return parametar1;
}
public int WriteNumber(int parametar2)
{
return parametar2;
}
public Calculator(int operand1, int operand2)
{
this.operand1 = operand1;
this.operand2 = operand2;
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28).ToString();
Console.WriteLine(n);
Console.ReadLine();
}
}
}
I think you are lacking some object oriented programming concepts. Constructor is pretty much a method that initializes an instance of a class.
Are the variables in the constructor supposed to be the named the same
as the ones in the methods?
Constructor parameters have to be named. But there is no connection between constructor params and method params. These are just separate members of a class.
How do I create an instance of the constructor in the main method?
You create an instance of a class but not a constructor. Although construction is being called when you initiate an object using new keyword.
How do I give it some random values?
Depending on the type. For integer for example you can use new Random().Next().
How do I call the two methods via their instances?
I guess... just call... Just like that:
calc.Method1();
calc.Method2();
Question 1:
Yes and No - Yes because they can be named similarly or identically and still function because of their scope. No because in your example code you would want them to represent what values they'll be holding so you can, at a glance, understand their purpose. For simplicity, in the examples I display I will keep them as named in your example.
I suggest googling Scope and lifetime of Variables and Naming Conventions.
Also, it would be wise to apply either fields or properties to your Calculator class so the constructors values are stored for use by the methods within the class. Should this be your intent for the parameters.
Question 2:
Create an instance of the Calculator class
var calc = new Calculator(); //calc can be named to anything you want.
Question 3:
Using a instance of System.Random then producing a variety of random numbers like so.
var rnd = new Random();
var randomNumber1 = rnd.Next(0, 100);
var randomNumber2 = rnd.Next(0, 100);
//then using those in your Calculator.WriteNumber()
var calc = new Calculator(1,2); //without fields/properties this could be erroneous
var result = calc.WriteNumber(randomNumber1 + randomNumber2); //returns the sum of those to params.
Question 4:
You need to initialize an instance of the Calculator class - See Question 2. Then use that variable to access the methods eg:
var result = calc.WriteNumber(2); //returns 2
//or
var result = calc.WriteNumber(53 + 28); //returns 81
Here is some working code that you can learn from example. Hope this helps.
static void Main(string[] args)
{
//Create random numbers
var rnd = new Random();
var randomNumber1 = rnd.Next(1, 100); //get a random int between 1 and 99
var randomNumber2 = rnd.Next(1, 100); //and again
//Create instance of Calculator Class
var calc = new Calculator(randomNumber1, randomNumber2);
//Intro
string s = calc.WriteText("Hello World!");
Console.WriteLine(s);
//Do your addition method
var n = calc.WriteNumber(53 + 28);
Console.WriteLine(n);
//Do new addition method
var result = calc.Add(); //Returns _operand1 + _operand2
Console.WriteLine(result);
//exit application
Console.ReadLine();
}
class Calculator
{
// Set fields for your constructor to use.
// Another valid option is using properties, google this as its beyond the scope of a basic tutorial
private int _operand1, _operand2;
public string WriteText(string parametar1)
{
return parametar1;
}
public int WriteNumber(int parametar2)
{
return parametar2;
}
public int Add()
{
return _operand1 + _operand2;
}
public Calculator(int operand1, int operand2)
{
//You don't need the this keyword
_operand1 = operand1;
_operand2 = operand2;
}
}
The object's fields don't have to be the same as the constructor's parameters, although it is common for that to be the case.
var calculator = new Calculator(53,28);
Use the Random class
calculator.WriteNumber(53+28);
Are the variables in the constructor supposed to be the named the same as the ones in the methods?
The variables you have used in the constructor are not declared in the class.
your class should be like this:
class Calculator
{
private int operand1 {get; set;} //need to declare the var before using
private int operand2 {get; set;}
private string Message {get; set;}
public string WriteText() //you don't need to send parameters to the function if you have already got them in the contructor
{
return Message;
}
public int GetSum()
{
return operand1 + operand2;
}
public Calculator(string Message, int operand1, int operand2)
{
this.Message = Message;
this.operand1 = operand1;
this.operand2 = operand2;
}
}
class Program
{
static void Main(string[] args)
{
Calculator CalcObj = new Calculator ("Hello word!", 53, 28); //That is how you can initialize a class object
string s = Calculator.WriteText(); //this will return you the string you passed in controller
Console.WriteLine(s);
string n = Calculator.GetSum().ToString(); //that will give you sum of two operand
Console.WriteLine(n);
Console.ReadLine();
}
}
For random numbers you can use
Random() method in C# to generate random numbers in main method and pass them to the contructor of the class and GetSum will give you some of those numbers
Recently, I've been working in performance/memory optimization and have stucked in the empty array initialization which uses generic method to initialize empty array:
Code implementation of generic empty array class:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
So, whenever creating empty array of any type,it has been called as like:
var emptyStringArray = EmptyArray<string>.Instance;
Such empty array declaration has been done in many places of codebase. I am confused how would it be differs in performance while using :
var emptyStringArray = new string[0];
I've asked to above code author and he has replied me :
Basically, all empty arrays are readonly, and are equal to one
another, which means that you can use the same instance (which will be
created lazily on demand during run-time)… That should reduce the
total number of allocations, reduce memory usage and GC pressure, and
should result in some improvement
Still, I am not able to understand how would EmptyArray Instance boost the performance in array declaration.
Is there any performance difference in code using following approach :
1st Approach :
var emptyStrArr = EmptyArray<string>.Instance;
var emptyFooArr = EmptyArray<Foo>.Instance;
var emptyBarArr = EmptyArray<Bar>.Instance;
2nd Approach :
var emptyStrArr = new string[0];
var emptyFooArr = new Foo[0];
var emptyBarArr = new Bar[0];
In the first code the static constructor is executed only once.So you are just creating one array and using it all the time. In the second code you are creating an array instance each time. That's the difference.
You can see it more cleary by changing the constructor:
static EmptyArray()
{
Instance = new T[0];
Console.WriteLine("Array of "+ typeof(T) + " is created.");
}
var s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
var i = EmptyArray<int>.Instance;
i = EmptyArray<int>.Instance;
// output:
// Array of System.String is created.
// Array of System.Int32 is created.
This:
var emptyStringArray = new string[0];
Creates a new instance of an empty string array every time its called, with all the associated memory allocation overhead, whereas this:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
Only ever creates a single instance of the empty string array, regardless of how many times you call the Instance field.
jus to illustrate a bit how this can boost performance and memory you can try this
using System;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
var str = EmptyArray<string>.Instance;
var intTest = EmptyArray<int>.Instance;
var intTest1 = EmptyArray<int>.Instance;
var str1 = EmptyArray<string>.Instance;
Console.WriteLine(str.GetType());
Console.WriteLine(intTest.GetType());
if (ReferenceEquals(str,str1))
{
Console.WriteLine("References are equals");
}
if (ReferenceEquals(intTest,intTest1))
{
Console.WriteLine("References are equals");
}
}
}
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
}
you can see that no other allocation is needed even for value type and given that allocation and destruction of objects it's time and memory consuming you can enhance your code by doing this
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
I'm trying to implement a simple plugin system which will allow people to write the following:
[Plugin("A plugin function")]
public static int PluginFunction(int a, int b)
{
return a + b;
}
and then drop the DLL containing this function into a folder where it will be scanned by the application and show up as an available function at runtime. This all works fine, so far so good, the PluginAttribute class is what you would expect, just a description string for the function.
However, I'd like to allow the plugin writer to specify default values for the parameters. This is OK for values which are constant at compile time and then deduced via reflection, but I'd like a way to specify defaults for more complex types which will be created at runtime. Has anyone implemented something similar? The primary goal is to make it simple to implement plugin functions - I'm trying to avoid complex scaffolding but accept that my nice simple system is not going to cut it if I want this feature. I'm also happy to have some complexity in the application code which makes the system appear simple to the plugin writer.
Thanks,
Charlie.
Update:
I'm going with a combination of what's been suggested here, the closest is what Peter O. came up with - here's a version:
[Plugin("A plugin function")]
[Defaults(typeof(AdderDefaults))]
public static int Adder(int a, int b)
{
return a + b;
}
public static class AdderDefaults
{
public static int a { get { return 1; } }
public static int b { get { return 2; } }
}
[Plugin("Another plugin function")]
[Defaults(typeof(TexturizerDefaults))]
public static Bitmap Texturize(Bitmap source, Point offset)
{
return result;
}
public static class TexturizerDefaults
{
// no default for source parameter
public static Point offset { get { return new Point(16, 16); } }
}
This allows parameters to be skipped and specified by name. No compile time checking but that's OK - checking these at runtime is acceptable.
Maybe you can create an attribute which refers to a type
containing default values for the plugin. Example:
[PluginDefaults(typeof(MyPluginDefaults))]
The class MyPluginDefaults could then look like:
public class MyPluginDefaults {
int Parameter1 { // First parameter
get { return 0; } // default value for 'a'
}
int Parameter2 { // Second parameter
get { return 4; } // default value for 'b'
}
// Additional parameters would be called Parameter3, Parameter4, and so on.
}
There are lots of way to do that, the simpliest is to use a simple convention :
[Plugin("A plugin function")]
public static int PluginFunction(int a, int b)
{
return a + b;
}
public static object[] PluginFunctionDefaultArguments()
{
return new [] { 0, 0 };
}
Each time you find a function marked with PluginAttribute search for a function having the same name with the DefaultArguments sufix, no parameters and an object[] return type. Then call it and store the values somewhere. You should also support the default values to be specifed using the dedicated C#/VB syntax (it is found in the DefaultValue member for the parameter)
One way would be to have property Defaults for each of the classes. It returns an object that can be queried for the defaults, for example like this:
object[] pluginFunctionDefaults = FooPlugin.Defaults["PluginFunction"];
(Obviously, you wouldn't have code exactly like this in your application.)
And the declaration of the defaults could look like this:
class FooPlugin
{
static FooPlugin()
{
var bar = new Bar();
Defaults = new DefaultValues()
.Add(() => PluginFunction(42, 13))
.Add(() => AnotherFunction(bar));
}
public static DefaultValues Defaults { get; private set; }
// actual methods of the class
}
Using expressions like this means that the types of the defaults are checked at compile time. The DefaultValues class parses the expressions and stores the parameters. It could look something like this:
class DefaultValues
{
private readonly Dictionary<string, object[]> m_expressions =
new Dictionary<string, object[]>();
public DefaultValues Add<T>(Expression<Func<T>> func)
{
var methodCall = ((MethodCallExpression)func.Body);
var name = methodCall.Method.Name;
var arguments =
methodCall.Arguments
.Select(Evaluate)
.ToArray();
m_expressions.Add(name, arguments);
return this;
}
private static object Evaluate(Expression expression)
{
return Expression.Lambda<Func<object>>(
Expression.Convert(expression, typeof(object)))
.Compile()();
}
public object[] this[string methodName]
{
get { return m_expressions[methodName]; }
}
}