C# static - What does the definition on MSDN mean? - c#

Use the static modifier to declare a
static member, which belongs to the
type itself rather than to a specific
object.
???
My encounter with this static keyword occurred when I defined a variable public int abc. When the value of this variable changed withing the brackets of while, or within the brackets of if, or within the brackets of methods, these changes were not valid, were not reflected, were not know outside the brackets. So just a hit trial. I made the variable static and all problems solved.
But why??

The difference between a static and a non-static member (not variable) is that a static member is unique over the whole runtime of a program (i.e. there is only one static member instance) whereas a non-static member is associated with an object instance (i.e. there is a member instance for each instance of the corresponding object). This is in a bit more words what the definition says.
How this all applies to what you wrote in regard to changes not reflected im not too sure - maybe you should post the corresponding code.

I did not understand what you meant but
static variables are variables at the class level - they do not belong to an instance of an object but to the class itself. They can be used and accessed without instantiating any instance.
An instance (non static) variable on the other hand belongs to the instance itself.

If you have a class:
public class Car {
public static readonly int Wheels = 4;
public static int Count {get;set;}
public string Make {get;set;}
public string Model {get;set;}
public int Year {get;set;}
public Car() { Car.Count = Car.Count + 1; }
public string SoundOff(){
return String.Format("I am only 1 out of {0} car{1}",
Car.Count, (Car.Count > 0 ? "s" : String.Empty));
}
}
Then, every time you create a car, the count will increase by one. This is because the Count property belongs to the Car class, and not to ever object you've created.
This is also useful because every car can have knowledge of the Car.Count. So, if you created:
Car sportster = new Car {
Make="Porsche", Model="Boxster", Year=2010 };
sportster.SoundOff(); // I am only 1 out of 1 car
You can do other processing and Count will be known to all objects:
Car hybrid = new Car { Make="Toyota", Model="Prius", Year=2010 };
hybrid.SoundOff(); // I am only 1 out of 2 cars
sportster.SoundOff(); // I am only 1 out of 2 cars
So, in other words, you should use static when you want something to:
Be accessible at the class-level so all objects know of it (Car.Count instead of hybrid.Count)
Represent the class and not the object (Car.Wheels won't change)
There are other reasons to use static, like Utility classes, extension methods, etc. But this should answer your question about the MSDN wording.

It's probably because you're creating multiple copies of the class, and each class has its own values for that member.
By change it to static, all instances share the same copy of the member variable.
The behavior that you're observing probably indicates a problem in your while and if expressions. If you post some sample code, I might be able to help further.

Related

Trouble understanding reference types / reference copying in Service Locator implementation

In implementing a Service Locator, I've come across something I'm confused about with regards to reference types.
In the code below, I have a static class ServiceLocator which exposes 2 static methods, GetService and ProvideService - get returns the current service, and provide takes a new service as an argument and assigns it to the current service variable. If the provided service is null, it assigns currentService to a static defaultService initialised at the start of the class declaration. Simple stuff:
public static class ServiceLocator {
private static readonly Service defaultService = new Service();
private static Service currentService = defaultService;
public static Service GetService() {
return currentService;
}
public static void ProvideService(Service service) {
currentService = service ?? defaultService;
}
}
What i'm confused about is this: I have a separate class which stores a reference to the currentService at the start of its class declaration in the variable named referenceToCurrentServiceAtStart. When I provide the service locator with a new Service instance to update the current service, referenceToCurrentServiceAtStart appears instead to maintain the reference to defaultService:
public class ClassThatUsesService {
private Service referenceToCurrentServiceAtStart = ServiceLocator.GetService();
private static ClassThatUsesService() {
ServiceLocator.ProvideService(new Service());
// this variable appears to still reference the defaultService
referenceToCurrentServiceAtStart != ServiceLocator.GetService()
}
}
So the references appear to follow this kind of chain:
referenceToCurrentServiceAtStart -> defaultService -> (Service in memory)
Which is understandable, since referenceToCurrentServiceAtStart simply copies the currentService reference. However, the behaviour I'm looking for/would like is for referenceToCurrentServiceAtStart to always reference whatever currentService references, so it's updated by Provide(). Something more akin to:
referenceToCurrentServiceAtStart -> currentService -> (Service> in memory)
So, is this behaviour possible? I'm really unsure of how I'd achieve this kind of reference behaviour. I'm new to C# so it's very possible there's some obvious language feature I'm clueless about. Any help would be greatly appreciated.
is this behaviour possible?
No, not as you've described it. As you're already aware, all you get is a copy of the original reference. Changing the original reference doesn't change the copy, any more than copying the value of an int variable to another would allow you to later change the original and have the copy change:
int original = 17;
int copy = original;
original = 19;
// "copy" is still 17, of course!
If you want to always have the current value of the reference in ServiceLocator, then you should just always retrieve the value from that class, rather than using a local field. In your above example, you might indirect through a property, e.g.:
public class ClassThatUsesService {
private Service referenceToCurrentServiceAtStart => ServiceLocator.GetService();
}
It's a one character change (the = becomes =>), but don't be fooled. It's a significant change in implementation. What you wind up with instead of a field, is a read-only property (i.e. has only a get method and no set method), where that property's get method calls the ServiceLocator.GetService() method and returns the result.
Personally, I wouldn't bother. Unless you have some very strong expectation that the implementation of referenceToCurrentServiceAtStart will change in the future, you should just call ServiceLocator.GetService() directly. Don't even have the referenceToCurrentServiceAtStart property. Since the code expects to always get the current value, the best way to ensure that is to just always get the current value, straight from the class where that value is stored.
Finally, I'll take the opportunity to show a scenario that is similar to what you're asking, but not exactly. In particular, because you're trying to store the reference in a class field, the above is how you need to do it. But, the latest C# has "reference return values", which must be stored in "ref locals". Since you want to reference a static field, which is guaranteed to always exist, you can in fact return a reference to the field, store that in a local, and when you retrieve the local variable's value, it will always have whatever is in the field, because it's a reference to the field, not a copy of it.
You can see the example in the documentation (see links above), but here's another example that is more similar to what you're doing:
class Program
{
static void Main(string[] args)
{
// stores a reference to the value returned by M1(), which is to say,
// a reference to the B._o field.
ref A a1 = ref B.M1();
// Keep the original value, and create a new A instance
A original = a1, a2 = new A();
// Update the B._o field to the new A instance
B.M2(a2);
// Check the current state
Console.WriteLine($"original.ID: {original.ID}");
Console.WriteLine($"a1.ID: {a1.ID}");
Console.WriteLine($"a2.ID: {a2.ID}");
}
}
class A
{
private static int _id;
public int ID { get; }
public A()
{
ID = ++_id;
}
}
class B
{
private static A _o = new A();
public static ref A M1()
{
// returns a _reference_ to the _o field, rather than a copy of its value
return ref _o;
}
public static void M2(A o)
{
_o = o;
}
}
When you run the above, you'll get this output:
original.ID: 1
a1.ID: 2
a2.ID: 2
In other words, the variable a1 winds up yielding the same value found in a2, which is the new object passed to the B.M2() method to modify the B._o field, while the original copy of the B._o field value remains a reference to the original object that field referenced.
This doesn't work in your case, because the ref value that's returned has to be stored in a ref local. You can't put it into a class field. But it's similar enough to your scenario that I wanted to mention it, in case you want to change your design to allow that, or want to use that technique in some other scenario that does work in that way.

c# object by name in static method

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

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

Why can a class not have a static or constant property and an instance property of the same name?

I've never really questioned this before until now. I've got an input model with a number of fields, I wanted to present the string names of the properties through the input model so that my Grid can use them:
public class SomeGridRow
{
public string Code { get;set; }
public string Description { get;set; }
public const string Code = "Code";
}
Obviously, this gives the error:
The type 'SomeGridRow' already
contains a definition for 'Code'
Why can the CLR not cope with two properties of the same name which are, in my eyes, separate?
string code = gridRow.Code; // Actual member from instantiated class
string codeField = SomeGridRow.Code; // Static/Const
I'm now just using a child class called Fields within my inputs now, so I can use SomeGridRow.Fields.Code. It's a bit messy, but it works.
Because you can also access static (or, non-instance in this case) properties in the same way (inside the same class), and it would be a bit confusing, for example:
public class SomeGridRow
{
public string Code { get;set; }
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
Because both this:
public class SomeGridRow
{
public string Code { get;set; }
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
And this:
public class SomeGridRow
{
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
are valid ways to access properties, static or not. It doesn't answer the "why can't I?" question, but more of the why it's not allowed...it would be far too ambiguous IMO.
It probably could, but the designers of C# wanted to avoid ambiguities that can come from such use (abuse?) of language features.
Such code would end up being confusing and ambiguous to users (did I want the instance or the static method call?, Which one is right?).
In addition to the points already made about ambiguity, i would say that the naming needs to be relooked in such a case.
If two variables / fields having the exact same name in the same context i.e class but different values to me sounds more like a naming issue.
If they are exactly same, you dont need 2 fields.
If they are slightly different, you should have more accurate names.
In some other languages with a similar syntax, one can access a static member through an instance. So you could access both string.Empty and "abc".Empty.
C# doesn't allow this (though it does sort of from inside the class or a derived class, in that you can omit the class name for a static member and can omit this for an instance member), primarily to avoid confusion (I find it more handy than confusion tbh, but that's just me, I like switch fall-through too so what do I know).
Having introduced a stricter rule to allow for less ambiguity, it would be counterproductive to allow a new looser rule on the back of it that allowed for more. Think how many "why must I use this with property X but not property Y?" questions SO would have if it was allowed (we'd have to force this with property X to be clear we meant the instance member).

C# - how can a constructor be created that takes variables before they are declared?

Based on my question - take the following code:
class Nevermore60Customer: GenericCustomer
{
public Nevermore60Customer(string name, string referrerName)
: base (name)
{
this.referrerName = referrerName;
}
private string referrerName;
private uint highCostMinutesUsed;
To me, it appears the variable "referrrerName" is being initialized "after" it is being referenced as a passed parameter in the constructor.
public Nevermore60Customer(string name, string referrerName)
Am I worng, and if so how? Or if I am right and it is being initialized after it is being referenced in the constructor, how is it possible?
Thanks
The position of the variable declaration compared with the constructor is irrelevant to C#.
It would make this easier to discuss if you had different names for the parameter and field though:
class Test
{
public Test(string parameter)
{
this.field = parameter;
}
private string field;
}
Basically the field "exists" before the constructor is called. If the field is declared with an initializer, like this:
private string field = "default value";
then that initializer is run before the constructor, even though it may come after it within the source code.
The constructor argument is not an alias for the field. It hides the field name, this code won't work:
public Nevermore60Customer(string name, string referrerName) : base (name)
{
referrerName = referrerName; // bad
}
By using the "this." prefix, you can tell the compiler to assign the argument value to the field. It is a very common pattern, avoids having to come up with another name for the argument. Or do something awkward like prefixing the field name with, say, an underscore.
Not sure I understand the question. Your constructor has a strign parameter, referrerName, that you are assigning TO a private class variable, also called referrerName. I don't see where this.referrerName is referenced before its initialization?
this.referrerName refers to the class member declared as private string referrerName;
The referrerName to the right of the = is the parameter to the constructor.
It doesn't matter how you order the private members of the class and the constructor, the private members will always be initialized first.
C# is an object oriented language and you seem to confuse plain C procedural language concepts with C#. Unlike C, in C# the order of declaration does not matter as long as the instance is initialized before accessing and is within the scope.

Categories