c# object by name in static method - c#

My question is: Can I define a static method "meth1" in a static class "classB" that, when called from "classA", searches for a specific field (in "classA", not in the class in which is defined)?
I try to explain better: I need to do something like this:
public class classA
{
string someText;
int anInt;
bool trueOrFalse;
public classA()
{
...
...
var variable = classB.meth1("variableName");
...
...
}
}
public static classB
{
public static object meth1(string name)
{
...
... //use "name" to find the variable with that name in the class from which "meth1" is called.
...
}
}
That because I have to read a backup of "last run values" of variables contained in a .txt file, written line by line as "variable name = value".
So I read the .txt, create an hashtable "backupHashtable" which contains ("variable name";"value"), and then I want to search variables by string "variable name" and reset them to "value".
If someone of you knows a better procedure I'm listening. Maybe the use of a Dictionary?
Thank you!
UPDATING
Ok, now I have a clearer idea of what I want to do: I want to implement a class "ClassB", separate from my main class "classA". In this new class I would have a "meth1" method which, running in a separate thread, saves every 10 seconds (for example) the state of some variables belonging to "classA". To communicate the "meth1" what are the variables that he has to save, I want to use a list containing the names (in the format "string", that's what I thought, but I guess it's not the only way) of these variables.
If you're wondering why I want to do this in a separate thread the answer is this: my application performs some recognition operation of some objects in live stream images from multiple cameras and then ancillary operations must be isolated as much as possible from the main code to increase the speed of execution.
Now, perhaps, it is more understandable what I said before.

Yes, but you also need to pass a reference to the instance of A. Then use reflection to get or set the property.
public static void Meth1(object obj, string propertyName)
{
var prop = obj.GetType().GetProperty(propertyName);
var value = prop.GetValue(obj);
...
}
If I were to get values from a textfile into a class, I think I'd load them in a dictionary first, and then set all properties one by one. (Maybe unless there are, say, hundreds of properties). When using reflection, there is a chance that the textfile contains the name of a property you don't want to be changed from outside.
object value;
if (dict.TryGetValue("someProperty", out value)) { a.SomeProperty = value; }

Related

Retaining a value obtained from file within the return value of a method

Assuming I will need to access the values contained within a given file a small number of times, from different methods, can I include some sort of boolean value within a method to determine whether or not it is appropriate to call the file?
Lets say I have the file config.cfg. In that file, there are three values:
string/name>max|
bool/adult>yes|
int/age>20|
The method getUserName() returns the value of "max". It does this by calling the file:
using (StreamReader reader = new StreamReader(path))
{
//get line beginning with string/name here
return //string value containing name
}
Let's assume I need to use the value of name several times, as well as the values isAdult and clientAge. Rather than accessing the file over and over again, it could be much easier to save the requested value in some form of static variable. However, this variable still needs to be changed in value at least once, when the method is first called.
Can I do this inside the method getUserName()?
Furthermore, is this idea even possible within the bounds of OOP? Is it a similar concept to Prefetch?
It really looks to me that you need to access a field in a lazy way (i.e. only if needed, when needed). If so .NET has Lazy class for such cases which also provides thread safety out of the box:
public static Lazy<string> Name { get; } = new Lazy<string>(() => ReadNameFromFile());
Lazy will also ensure that you only create value once (i.e. call initiailization method) and on later calls it will simply return already retrieved value.
Create a static class. Something like this:
public static class ClientConfig{
public static string Name{get;set;}
public static bool IsAdult{get;set;}
public static int Age{get;set;}
public static void Load(){
// load your values
// ClientConfig.Name = name from file etc.
}
public static void Save(string newName, int age, bool value){
// save your values to the config file
}
}
And call ClientConfig.Load() first time when your app starts, for example (or whenever you need to retrieve config data)

c# enumerate values from new instance of a class

I asked a question on here earlier but I didn't explain correctly so I got the right answers to the wrong question.
I am creating an instance of a class, when I get the class back it returns a number of results which are private in the class I am calling.
I am unable to change this class and make them public for various reasons.
What I need to do is enumerate through and get a value of the Text variable that is held:
public class StringReader
{
private string LongText = "this is the text i need to return";
private string Text;
public StringReader()
{
Text = LongText;
}
}
In the method I am trying to get the value of Text I am calling
StringReader sReader = new StringReader();
List<StringReader> readers = new List<StringReader>() { sReader};
Readers has LongText and Text but I am struggling to get the text value back.
Instead it just returns the Type to me.
You will need to use reflection to access the private field. You can access all fields of a type using the GetField(s) method. You can access their values using the GetValue function
public string GetLongText(StringReader reader)
{
// Get a reference to the private field
var field = reader.GetType().GetField("LongText", BindingFlags.NonPublic |
BindingFlags.Instance)
// Get the value of the field for the instance reader
return (string)field.GetValue(reader);
}
Fields declared as private are inaccessible outside the class that defined them. You cannot read their value without either
Changing their visibility
Adding an accessor method/property with public visibility
Using reflection (this is not recommended, there is almost always a better way)
What is the use-case here? What are you trying to achieve? If you define your problem a bit more generally maybe we can give a better solution.
Without modifying the class, it's impossible using best OOP practices. They are set to private to mean they can only be accessible inside the class only. You need to speak to the original developer of the class and ask why they cannot make a public getter for the private field that would look like this:
public string getText(){
return this.Text;
}
This would mean the string can't be modified, but you can at least read it.

Datastructure to represent extensible and unique values

I've a small problem. I've a application monitoring part in a framework which is used by multiple applications.
Right now I've a functionality like this:
public enum Vars
{
CPU,
RAM
}
public void Add(Vars variable, object value)
{
[...]
}
The Variable which is used as Parameter in the Add method will be used as the name of the entry in the database.
Now I got the requirement, that applications can specify own variables outside the framework. Because you can't inherit from an enum this causes some trouble.
I see basicly 2 possibilities (which are bot not very satisfying in my opinion) to solve this.
Possibility 1:
public void Add(enum variable, object value)
This method would accept all sorts of enums, so users could use the Vars enums as well as enums which they've defined by themself. The problem with this solution: It would be possible, that users use the same names in both.. application and framework. I'm not able to differ between two enums with the value "CPU" (Framework may store percent values as "CPU", application may store process cpu usage as "CPU").
Possibility 2:
The second method would be an class instead a enum, something like:
public class Vars
{
public const string CPU = "CPU";
public const string RAM = "RAM";
}
The drawbacks here:
1. More to write.
2. I would have to define parameters as strings:
public void Add(string variable, object value);
This could lead to missuse as well (Applications which add strings directly instead defining a class which inherits from Vars).
Any thoughts on how to define a model which:
Can be inherited (to extend the values by applicationspecific values)
Can be used as a parameter
Ensures, that there are no double (=same value) entries
?
The context is not completely clear, but what about creating a class
public class Vars
{
public static Vars CPU = Vars.Get("CPU", 1);
public static Vars RAM = Vars.Get("RAM", 2);
//You can keep one of the params, name or id
private Vars(string name, int id)
{
...
}
public static Vars Get(string name, int id)
{
//check if id or name exists in static dictionary, and return that instance or create new one
}
}
public void Add(Vars variable, object value);
Now user can create any kind of Parameter and pass to the method,
Vars newVar = Vars.Get("MyNewParam", 10);
You can easily check if the passed param is one, about which you know
Get method returns same instance if the params are the same

Get value of non-existing variables by calling a method

As strange as it might sound, I want to access something that is not.
Here's an example:
int tempVar = myObject.myVar // myVar does not exist;
In reality I want the class to run a method, that would take the non-existing variable as a parameter:
object returningVariables(string variableName)
{
object desiredObject; // a concrete object that I have stored somewhere in an array inside the class
// going trough some List that contains names of all variables, when it finds it
// return it
return desiredObject;
}
I'll try to explain in a concrete example what I want to achieve and why.
I have a class that stores stats of an object: name, level, speed, size, etc.
They are supposed to be accessed trough a method StatData getStat(string statName);
Stats are created trough a method void MakeStat(). The problem began when some stats were created in the class as public variables and accessed by other classed not trough the getStat() method.
Now that the public variables are changed, deleted or new ones added it takes some refactoring to get the app working again. And it looks bad when there are mixed calls with direct access to a public variable and a method for the same thing.
Please note, I do know how to fix my code the standard way; I am merely interested if above described technique will work.
Sounds like DynamicObject would help you here. You can override different methods for of that class for whatever is being called/accessed on that object: members, invocations, etc. Using dynamic means you won't be able to use intellisense anymore however. You can find more info here.
public class MyDynamicObject : DynamicObject {
public override bool TryGetMember(GetMemberBinder binder, out Object result){
if (binder.Name == "myVar"){
result = "xyz";
return true;
}
result = null;
return false;
}
}
// Usage
dynamic x = new MyDynamicObject();
Console.WriteLine (x.myVar); // will output "xyz"

What are getters and setters used for in C#? How do I use them with an array?

1) I'm still quite new to programming and have read a bit about getters and setters. But I really don't understand why they are used.. Could anyone explain it, or point me to an article? (The ones I read were not really understandable for me...)
2) In my current project I have a class where I declare and initialize an array of structs. I now need to access the array from another class, but it gives me the error: An object reference is required to access non-static member 'BaseCharacter.Attributes'.
I figures this could mean I need to use getters and setters? But how does this work for arrays?
Thanks in advance!
Simon.
EDIT: 2nd question got solved, which brings me to something else. When I want to use some class in another one, I'm making a new instance of the class, right? And this means I get the original values?
But that's not what I want.
The second class is used to generate the UI, and needs the values I'm keeping in the first class.
At some point I will implement save files (XML or even on a server in later stage). Can I then just get the values from those files?
For the getters and setters (the things that use them are called Properties) it's just a convenient and nice-looking way to make people think they're using a variable, but to do some computation whenever the variable is updated or accessed. For instance:
BankAccount.Interest
looks better than
BankAccount.GetInterest()
Even though you can calculate the interest at the time it is requested in both cases.
They are also used to make a variable be able to be accessed from outside the class, but changeable only from within the class with this technique:
public double Interest {
get;
private set;
}
For an example of a setter being used, if you've ever used Windows Forms and updated a control's Height or Width property, you're using a setter. While it looks like you're using a normal instance variable like c.Height = 400, you're really letting c update it's position by redrawing at a new place. So setters notify you exactly when a variable is changed, so your class can update other things base on the new value.
Yet another application of Properties is that you can check the value people try to set the property to. For instance, if you want to maintain an interest rate for each bank account but you don't want to allow negative numbers or numbers over 50, you just use a setter:
private int _interestRate = someDefault;
public int InterestRate {
get { return _interestRate; }
set {
if (value < 0 || value > 50)
throw new SomeException(); // or just don't update _interestRate
_interestRate = value;
}
}
This way people can't set public values to invalid values.
For your second question, you can do one of two things depending on what you're trying to do.
One: You can make that member static. That means that just one of them exists for the entire class instead of one per instance of the class. Then you can access it by ClassName.MemberName.
You can do that this way:
// inside the BaseCharacter class definition:
public static SomeStruct[] Attributes = new SomeStruct[size];
// then to use it somewhere else in your code, do something with
BaseCharacter.Attributes[index]
Two: You have to make an instance of the class and access the array through that. This means that each object will have its own seperate array.
You'd do that like this:
BaseCharacter bc = new BaseCharacter();
// use bc.Attributes
The second one is probably what you'll want to do, since you probably will want to modify each character's attributes seperately from all the other characters.
Actually the error you mention is not related to the getters and setters concept, it's because after creating your class you need to create an object before using its members; think of the class as a template for a document and the object as the document
you are most likely doing something like this:
var someVar = BaseCharacter.Attributes;
When you should be doing something like this:
var someVar = new BaseCharacter();
var someOtherVar = someVar.Attributes;
And about why the getters and setters, Seth Carnegie's Answer covers it nicely.
If you are new to Object Oriented Programming, you may be missing an important concept, that is about encapsulation.
Fields (attributes) of a class should be accessed only from within the class (or it's inherited classes). That is, if we have a class person, only with a name, you can do
public class Person
{
public string Name;
}
So anywhere in your program, you will be able to access it by doing:
Person person = new Person();
person.Name = "Andre";
This works, but it's not encapsulated. In some languages like C++ or Java, it was done like this:
public class Person
{
private string _name;
public string setName(string newName)
{
this._name = newName;
}
public string getName()
{
return this._name;
}
}
Person person = new Person();
person.setName("Andre");
This makes our _name attribute encapsulated, it can only be retrieved by it's get and set methods (that is, by the interface of the class).
C# makes this easier, allowing getters and setters:
public class Person
{
private string name;
public string Name
{
get { return this.name; }
set { this.name = value; }
}
}
Person person = new Person();
person.Name = "Andre";
This is very much like the second example (Java/C++ way), but you treat Name as property, instead of methods, and leaving our name property encapsulated
1) They might seem optional but they allow you more control over code:
You're able to intercept new values and avoid them being set (e.g. to exclude pointless values). Also you're able to fire custom events in case a property is changed or updated (just like the WinForms controls do).
private string name;
public string Name
{
get
{
// running additional code, e.g. here I avoid returning 'null' for a name not set
if(name == null)
return "(Unknown)";
return name;
}
set
{
// checking incoming values, e.g. here I avoid setting an empty name
name = value != null && value.Length > 0 ? name : null;
// running more/additional code, e.g. here I raise an event
if(OnNameChange)
OnNameChange();
}
}
2) Without knowing the code it's hard to tell you the exact reason, but if you'd like to access some member variable or property you have to either create an object of that class or make the variable static (e.g. shared between all instances of the object):
class MyClass
{
public static int someNumber = 55;
public int thisNumber;
}
// ...
int someothervar = MyClass.someNumber; // access the static member variable
MyClass mc = new MyClass(); // create an object of the class
int yetanothervar = mc.thisNumber; // access the member variable

Categories