I'm trying to modify a bunch of static value variables as fields in a static class. They need to be initialized in some sort of structure with a string attached to them, but the outside world should be able to just get the variable directly.
Here's a basic code dump of what I'm trying to do (disregard the specifics inside of DoStuff(); just an example of the kind of operations I'm trying to do):
public unsafe static class StaticVariables
{
public static int foo;
public static int bar;
...
public static int bazinga;
static IEnumerable<StaticInteger> intList = new List<StaticInteger>
{
new StaticInteger(&foo,"foo"),
new StaticInteger(&bar,"bar"),
...
new StaticInteger(&bazinga,"bazinga")
};
public static void DoStuff()
{
foreach(StaticInteger integer in intList)
{
if(integer.identifier=="foo") *integer.pValue = 30;
if (integer.identifier == "bar") *integer.pValue = 23;
}
Console.WriteLine("{0} {1}", foo, bar);
}
}
public unsafe class StaticInteger
{
public int* pValue;
public string identifier;
public StaticInteger(int* pValue, string identifier)
{
this.pValue = pValue;
this.identifier = identifier;
}
}
I'm not able to grab the address of foo/bar where I want to. They're static/globals, so they shouldn't going anywhere. I can cheat and use fixed inside of DoStuff to initialize the list, but I want to be able to reference my list multiple times after initialization, and I'm not sure that's safe because we'd no longer be in the fixed block. Is there a way to tell the GC "Don't touch where you put this static variable please"?
I'd be super happy if the answer was "don't use pointers, do XYZ instead."
Using a properties with only a getter rather than fields you can limit users to only reading values & the values can be stored in a Dictionary rather than a list.
public static class StaticVariables
{
public static int foo { get {return values["foo"];}}
public static int bar { get {return values["bar"];}}
public static int bazinga { get {return values["bazinga"];}}
private static Dictionary<String,int> values = new Dictionary<String,int>();
static StaticVariables()
{
values.Add("foo",0);
values.Add("bar",0);
values.Add("bazinga",0);
}
public static void DoStuff()
{
values["foo"] =30;
values["bar"] =23;
}
}
Related
I wrote the code below and i want to access the private varibale in another class, i created instance of the class and tried to access it but couldn't. can someone point out what I did wrong in the code below?
using System;
namespace lab_first
{
public class AccessModifiers
{
private int Abc { get; set; }
private int bcd { get; set; }
}
class Program
{
static void Main(string[] args)
{
var acc = new AccessModifiers();
Console.WriteLine(acc.Abc)
}
}
}
You make members private so that nobody outside the class can access them.
This goes inline with the principle of information hiding.
Your example should look like this:
public class AccessModifiers
{
// You can only access this inside of the class AccessModifiers
private int Abc { get; set; }
internal void SetValue(int x){
// Access possible, because SetValue() is inside the same class
Abc = x;
}
internal int GetValue(){
// Access possible, because GetValue() is inside the same class
return Abc;
}
}
class Program
{
static void Main(string[] args)
{
var acc = new AccessModifiers();
// Abc is never modified directly, only indirectly.
acc.SetValue(5);
Console.WriteLine(acc.GetValue());
}
}
However, there is still a way to access the private member. It's called Reflection. However, note that private variables are considered an implementation detail and might change at any time, so you can't rely on it. E.g. someone might change the name from Abc to def and your Reflection-based approach fails.
You can either change private to internal or public in this case.
Another way is declaring the variables in the class as private and using C# Properties in the class to set and get the values of variables. this is called encapsulation which is a protective shield that prevents the data from being accessed by the code outside this shield).
public class AccessModifiers
{
private int _abc { get; set; }
private int _bcd { get; set; }
public int Abc
{
get
{
return _abc;
}
set
{
_abc = value;
}
}
public int Bcd
{
get
{
return _bcd;
}
set
{
_bcd = value;
}
}
}
I cant access static method from new object and not allow create same name non-static method.I need to use same name method static and non-static.
Foo class has some default variables. I create new object and set default variables.
Sample code block
class Foo
{
public void abc()
{
//...
}
public static string xyz(string s)
{
return "bla bla";
}
}
public void btn1_click()
{
System.Windows.Forms.MessageBox.Show(Foo.xyz("value"));
//Works OK
}
public void btn1_click()
{
Foo f1=new Foo();
//f1..
f1.xyz("value");
//Cant access non static method.
}
Thanks in advance.
If the class has default values, the correct place to populate them is in the class constructor:
public class Foo
{
public Foo()
{
// set default values here.
}
}
If you still want to use these default values as static members - no problem:
public class Foo
{
public static const int DEFAULT_INT_VALUE = 5;
public Foo()
{
IntValue = DEFAULT_INT_VALUE;
}
public int IntValue {get;set;}
}
I often find myself doing this:
class MyClass
{
public MyClass(int x)
{
this.x = x;
}
private int x;
...
}
Every time I add a new private member variable for configuration, I need to add it to the constructor's parameter list, to the constructor body, and to the class as a member. Is there a good programming pattern for avoiding the extra typing?
Generally speaking, If you instantiate a class with a bunch of private members that you have to pass into the constructor, you're doing something problematic already.
MyClass myClass = new MyClass(x, y, z, 7, 'c', someOtherClass)
If appropriate, you can encapsulate related fields into a struct or a different class like so
class MyClass
{
public MyClass(Coordinates coords)
{
this.coords = coords;
}
private Coordinates coords;
}
public struct Coordinates
{
public int X{get; set;}
public int Y{get; set;}
public int z{get; set;}
}
and then you can instanciate it with
MyClass myClass = new MyClass(new Coordinates() { X = 1, Y = 2, Z = 3 });
Without a particular implementation, It's kinda hard to determine the optimal solution, but if you don't actually have to set the fields from outside your class, you can do something like
class MyClass
{
public MyClass()
{
}
private int x = 2;
...
}
or
class MyClass
{
public MyClass()
{
this.x = 2;
}
private int x;
...
}
I find that I can abuse inheritance to accomplish my goal. I set up a "Loader" subclass that has the sole purpose in life of plugging in the dependencies of the base class. Then we can work with the base class and forget about the loader.
Then again, this has the horrible side-effect of preventing use of these protected member variables in the base constructor -- we need to use a .Start() function or something like that instead. So, this is a pretty bad solution, although saving some keystrokes.
public class MyClass
{
protected int param1;
protected int param2;
public void DoStuff()
{
Console.WriteLine(param1 + param2);
}
}
public class MyClassLoader : MyClass
{
public MyClassLoader()
{
param1 = 1;
param2 = 2;
}
}
class Program
{
static void Main(string[] args)
{
MyClass myObj = new MyClassLoader();
myObj.DoStuff();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
I have such class in c#:
public class Foo
{
public static readonly int SIZE = 2;
private int[] array;
public Foo
{
array = new int[SIZE];
}
}
and Bar class:
public class Bar : Foo
{
public static readonly int SIZE = 4;
}
What I want to accopmlish is to create a Bar instance with array size taken from overrided SIZE value. How to do it properly?
You can't do it this way. You could use a virtual method:
public class Foo
{
protected virtual int GetSize(){return 2;};
private int[] array;
public Foo
{
array = new int[GetSize()];
}
}
It's also possible to use reflection to look for a static field SIZE, but I don't recommend that.
Your SIZE constant is static, and static fields aren't inherited - Foo.SIZE and Bar.SIZE are two different constants that have nothing to do with each other. That's why Foo's constructor call will always initialize with 2, not 4.
What you can do is create a protected virtual void Initialize() method in Foo that initializes the array with 2, and override it in Bar to initialize it with 4.
You cannot inherit static fields; instead use the below:
public class Foo
{
protected virtual int SIZE
{
get
{
return 2;
}
}
private int[] array;
public Foo()
{
array = new int[SIZE];
}
}
public class Bar : Foo
{
protected override int SIZE
{
get
{
return 4;
}
}
}
Virtual is like saying "This is the default value of the base class"; whilst Override changes the value on the class implementing "Foo".
I want to convert this C++ code to C#:
typedef struct consoleCommand_s
{
char* cmd ;
void (*function)() ;
} consoleCommand_t ;
static consoleCommand_t commands[] =
{
{"clientlist", &CG__Clientlist},
{"say", &CG_Say},
{"nick", &CG_Nick},
{"logout", &CG_Logout}
} ;
// e.g.
static void CG_Logout(void)
{
// Logout
}
The closest i have come is this:
public class Class1
{
// public delegate int Calculate (int value1, int value2);
public delegate void fnCommand_t();
public class consoleCommand_t
{
public string strCommandName;
public fnCommand_t fnCommand;
public consoleCommand_t(string x, fnCommand_t y)
{
this.strCommandName = x;
this.fnCommand = y;
} // End Constructor
} // End Class consoleCommand_t
public static void Nick()
{
Console.WriteLine("Changing Nick");
} // End Sub
public static void Logout()
{
Console.WriteLine("Logging out");
} // End Sub
// string[] names = new string[] {"Matt", "Joanne", "Robert"};
public consoleCommand_t[] commands = new consoleCommand_t[] {
new consoleCommand_t("Nick", Nick),
new consoleCommand_t("Logout", Logout)
};
} // End Class Class1
Now I wanted to ask:
A) Why does Nick & Logout need to be static when all the rest is not ?
B) Is there no C-like way to initialize the commands array, that is, without new ?
You could do without having a class INSIDE another class and manage your default console commands in another.
public delegate void ConsoleCmd();
public class DefaultCommands
{
public static void Nick()
{
Console.WriteLine("I'm Nick!");
}
public static void LogOut()
{
Console.WriteLine("You're Fired!");
}
}
public class Console
{
private Dictionary<string, ConsoleCmd> mCommands;
public Console()
{
mCommands = new Dictionary<string, ConsoleCmd>();
mCommands.Add("Nick", DefaultCommands.Nick);
mCommands.Add("Logout", DefaultCommands.LogOut);
}
}
Accessing your commands would be as easy as:
ConsoleCmd command = mCommands["Nick"];
command();
EDIT: Failed to mention this. This is to point to the OP that there are other better methods to achieve what he wants to do. And probably doesn't answer his question but I hope will point him to the right direction in terms of his switch from functional programming language to purely object-oriented language.
Nick & Logout may be non-static:
public void Nick(){}
public void Logout(){}
public consoleCommand_t[] commands = new consoleCommand_t[] {
new consoleCommand_t("Nick", this.Nick),
new consoleCommand_t("Logout", this.Logout)
};
B) Is there no C-like way to initialize the commands array, that is, without new ?
Don't get hung up on the new keyword in C#, it's just how initialisation is written. In C#, the analagous distinction between stack allocation and heap allocation is made using struct vs class. (So you might like to make your ConsoleCommand_t a struct.)
Edit: And with a struct you can also do:
new consoleCommand_t() {strCommandName = "Nick", fnCommand = Nick}
And skip writing the consoleCommand_t constructor. That's about as close as you can get to your C-style struct initialization, I think