Hi I was reading on the microsoft website when I found this, can someone please explain why this is bad programming, because I see it in the way of doing more in less lines of coding. Ps I am still a novice in classes...
It is a bad programming style to change the state of the object by using the get accessor. For example, the following accessor produces the side effect of changing the state of the object every time that the number field is accessed.
private int number;
public int Number
{
get
{
return number++; // Don't do this
}
}
Certainly...
Get is read by most developers as a read only action, and people reading your code will not expect a Get property to be modifying any data. It's a convention, but when you think about it, one that makes sense - it helps us all to understand one another's code.
In the example you cite, one approach would be to make this into two calls - a get, followed by a set to increment the variable... Another would be to implement a method to increment the variable and return the result.
There are perfectly valid reasons to modify the state of an object on get accessors, and that's why it's permitted (for example, for statistical purposes):
For example:
private int _timesMyCustomerWasAccessed;
private Customer _myCustomer;
public Customer MyCustomer
{
get
{
_timesMyCustomerWasAccessed++;
return _myCustomer;
}
}
That said, it's generally bad practice to make state changes on the object that affect how this object is observed from the outside (much worse if the change applies to the results of that very same property).
It's a syntax thing: get accessors are not supposed to have side effects, because they look weird and makes the code hard to understand.
In your example code. Imagine this code accessing the property:
Console.Write(String.Format("{0} {1} {2},
myObject.Number,
myObject.Number,
myObject.Number));
The output would be:
0 1 2
If you try to read that code, except if the object's side effects are perfectly documented, what would make you think that myObject.Number would give different results every time?
For your particular case, it would make much more sense if you had a method:
public int GetNumberAndIncrease()
{
return number++;
}
And when you read that code:
Console.Write(String.Format("{0} {1} {2},
myObject.GetNumberAndIncrease(),
myObject.GetNumberAndIncrease(),
myObject.GetNumberAndIncrease()));
The output is perfectly understandable by just reading that code
As given in your example, lets assume a situation.
You are developing an API in which you are providing the size of the collection(Number) you have restricted to use by the user, but you are allowing the user to see how many contents/items are there in the collection.
Now one has to get the counts at three different places- and in that case you are increasing the number every time he gets it, that is absolutely wrong.
Hope you got the point, why its a bad programming style.
Related
When I first began as a junior C# dev, I was always told during code reviews that if I was accessing an object's property more than once in a given scope then I should create a local variable within the routine as it was cheaper than having to retrieve it from the object. I never really questioned it as it came from more people I perceived to be quite knowledgeable at the time.
Below is a rudimentary example
Example 1: storing an objects identifer in a local variable
public void DoWork(MyDataType object)
{
long id = object.Id;
if (ObjectLookup.TryAdd(id, object))
{
DoSomeOtherWork(id);
}
}
Example 2: retrieving the identifier from the Id property of the object property anytime it is needed
public void DoWork(MyDataType object)
{
if (ObjectLookup.TryAdd(object.Id, object))
{
DoSomeOtherWork(object.Id);
}
}
Does it actually matter or was it more a preference of coding style where I was working? Or perhaps a situational design time choice for the developer to make?
As explained in this answer, if the property is a basic getter/setter than the CLR "will inline the property access and generate code that’s as efficient as accessing a field directly". However, if your property, for example, does some calculations every time the property is accessed, then storing the value of the property in a local variable will avoid the overhead of additional calculations being done.
All the memory allocation stuff aside, there is the principle of DRY(don't repeat yourself). When you can deal with one variable with a short name rather than repeating the object nesting to access the external property, why not do that?
Apart from that, by creating that local variable you are respecting the single responsibility principle by isolating the methods from the external entity they don't need to know about.
And lastly if the so-called resuing leads to unwanted instantiation of reference types or any repetitive calculation, then it is a must to create the local var and reuse it throughout the class/method.
Any way you look at it, this practice helps with readability and more maintainable code, and possibly safer too.
I don't know if it is faster or not (though I would say that the difference is negligible and thus unimportant), but I'll cook up some benchmark for you.
What IS important though will be made evident to you with an example;
public Class MyDataType
{
publig int id {
get {
// Some actual code
return this.GetHashCode() * 2;
}
}
}
Does this make more sense? The first time I will access the id Getter, some code will be executed. The second time, the same code will be executed costing twice as much with no need.
It is very probable, that the reviewers had some such case in mind and instead of going into every single one property and check what you are doing and if it is safe to access, they created a new rule.
Another reason to store, would be useability.
Imagine the following example
object.subObject.someOtherSubObject.id
In this case I ask in reviews to store to a variable even if they use it just once. That is because if this is used in a complicated if statement, it will reduce the readability and maintainability of the code in the future.
A local variable is essentially guaranteed to be fast, whereas there is an unknown amount of overhead involved in accessing the property.
It's almost always a good idea to avoid repeating code whenever possible. Storing the value once means that there is only one thing to change if it needs changing, rather than two or more.
Using a variable allows you to provide a name, which gives you an opportunity to describe your intent.
I would also point out that if you're referring to other members of an object a lot in one place, that can often be a strong indication that the code you're writing actually belongs in that other type instead.
You should consider that getting a value from a method that is calculated from an I/O-bound or CPU-bound process can be irrational. Therefore, it's better to define a var and store the result to avoid multiple same processing.
In the case that you are using a value like object.Id, utilizing a variable decorated with const keyword guarantees that the value will not change in the scope.
Finally, it's better to use a local var in the classes and methods.
Working on a problem for a test application I am building, and I can't seem to work out what to do. The app is essentially a questionnaire that is to be passed between two different people using the same device.
However, when I have a private setter for CurrentQuestion, the value never stays modified when being sent across to the new version of the activity. It always retains its original value of 1 (all other values stay modified though). When debugging though, I do see the value of the property increment by 1, it is just not retained.
As soon as I remove the private setter this resolves itself and it increments like normal, but I know this is bad practice, so I would like to find the correct way to do it.
Any help or guidance would be much appreciated, as I feel like I have tried a huge variety of different methods with no luck.
Setting an auto-poroperty like this assumes that all access and modification to that property will be done directly though the property itself, as opposed to using a method like you're doing to increment this property. Based on what you're doing here I would recommend this possible solution to your problem.
Set a backing field for the property and increment that in your NextQuestion method.
private int _currentQuestion;
public int CurrentQuestion => _currentQuestion;
public void NextQuestion()
{
_currentQuestion++;
}
This is the first time I face a problem like this. Not being this my profession but only my hobby, I have no previous references.
In my program I have added one by one several functions to control a machine. After I added the last function (temperature measurement), I have started experiencing problems on other functions (approx. 8 of them running all together. The problem I am experiencing is on a chart (RPM of a motor) that is not related to this function but is affected by it. You see the difference between these two charts with and without the temperature measurement running. The real speed of the motor is the same in both charts but in the second one I loose pieces on the fly because the application slows down.
Without the temperature function.
With the temperature function
Particularly this function is disturbing the above control and I think is because the work load is becoming heavy for the application and or because I need sampling so there is some time waiting to get them:
private void AddT(decimal valueTemp)
{
sumTemp += valueTemp;
countTemp += 1;
if (countTemp >= 20) //take 20 samples and make average
{
OnAvarerageChangedTemp(sumTemp / countTemp);
sumTemp = 0;
countTemp = 0;
}
}
private void OnAvarerageChangedTemp(decimal avTemp)
{
float val3 = (float)avTemp;
decimal alarm = avTemp;
textBox2.Text = avTemp.ToString("F");
if (alarm > 230)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.alarma;
player.Play();
timer4.Start();
}
else
{
timer4.Stop();
panel2.BackColor = SystemColors.Control;
}
}
I am wondering if running this function on a different thread would solve the problem and how I can do that? Or if there is a different way to solve the problem.Sample code will be appreciated.
Update, added method call.
This is how I call the method AddT
if (b != "")
{
decimal convTemp; //corrente resistenza
decimal.TryParse(b, out convTemp);
AddT(convTemp);}
This is how I receive the data from the serial and pass it to the class that strips out unwonted chars and return values to the different variables.
This is the class that strips out the unwonted chars and return the values.
And this is how I manage the serial incoming data. Please do not laugh at me after seeing my coding. I do a different job and I am learning on my own.
It's very hard to tell if there's anything wrong and what it might be - it looks like subtle problem.
However, it might be easier to get a handle on these things if you refactor your code. There are many things in the code you've shown that make it harder than necessary to reason about what's happening.
You're using float and decimal - float isn't that accurate but small and fast; decimal (tries) to be precise but especially is predictable since it rounds errors the way a human might in base-10 - but it is quite slow, and is usually intended for calculations where precise reproducibility is necessary (e.g. financial stuff). You should probably use double everywhere.
You've got useless else {} code in the Stripper class.
Your Stripper is an instatiable class, when it should simply be a static class with a static method - Stripper is stateless.
You're catching exceptions just to rethrow them.
You're using TryParse, and not checking for success. Normally you'd only use TryParse if you (a) expect parsing to fail sometimes, and (b) can deal with that parse failure. If you don't expect failure or can't deal with it, you're better off with a crash you learn about soon than a subtly incorrect values.
In stripper, you're duplicating variables such as _currentMot, currentMot, and param4 but they're identical - use only the parameter, and give it a logical name.
You're using out parameters. It's almost always a better idea to define a simple struct and return that instead - this also allows you to ensure you can't easily mix up variable names, and it's much easier to encapsulate and reuse functionality since you don't need to duplicate a long call and argument definition.
Your string parsing logic is too fragile. You should probably avoid Replace entirely, and instead explicitly make a Substring without the characters you've checked for, and you have some oddly named things like test1 and test2 which refer to a lastChar that's not the last character - this might be OK, but better names can help keep things straight in your head too.
You have incorrect code comments (decimal convTemp; //corrente resistenza). I usually avoid all purely technical code comments; it's better to use descriptive variable names which are another form of self-documenting code but one in which the compiler can at least check if you use them consistently.
Rather that return 4 possibly empty values, your Stripper should probably accept a parameter "sink" object on which it can call AddT AddD and AddA directly.
I don't think any of the above will fix your issue, but I do believe they're help keep your code a little cleaner and (in the long run) make it easier to find the issues.
your problem is in the parsing of the values you have
decimal.TryParse(a, out convRes);
AddA(convRes);
and don't check for failed values you only accept the value if it returns true
if(decimal.TryParse(a, out convRes))
{
AddA(convRes);
}
you may have more errors but this one is making you process 0 values every time the TryParse fails.
The example below may not be problematic as is, but it should be enough to illustrate a point. Imagine that there is a lot more work than trimming going on.
public string Thingy
{
set
{
// I guess we can throw a null reference exception here on null.
value = value.Trim(); // Well, imagine that there is so much processing to do
this.thingy = value; // That this.thingy = value.Trim() would not fit on one line
...
So, if the assignment has to take two lines, then I either have to abusereuse the parameter, or create a temporary variable. I am not a big fan of temporary variables. On the other hand, I am not a fan of convoluted code. I did not include an example where a function is involved, but I am sure you can imagine it. One concern I have is if a function accepted a string and the parameter was "abused", and then someone changed the signature to ref in both places - this ought to mess things up, but ... who would knowingly make such a change if it already worked without a ref? Seems like it is their responsibility in this case. If I mess with the value of value, am I doing something non-trivial under the hood? If you think that both approaches are acceptable, then which do you prefer and why?
Thanks.
Edit: Here is what I mean when I say I am not a fan of temp variables. I do not like code like this:
string userName = userBox.Text;
if (userName.Length < 5) {
MessageBox.Show("The user name " + userName + " that you entered is too short.");
....
Again, this may not be the best way to communicate a problem to the user, but it is just an illustration. The variable userName is unnecessary in my strong opinion in this case. I am not always against temporary variables, but when their use is very limited and they do not save that much typing, I strongly prefer not to use them.
First off, it's not a big deal.
But I would introduce a temp variable here. It costs nothing and is less prone to errors. Imagine someone has to maintain the code later. Better if value only has 1 meaning and purpose.
And don't call it temp, call it cleanedValue or something.
It is a good practice not to change the values of incoming parameters, even if you technically can. Don't touch the value.
I am not a big fan of temporary variables.
Well, programming is largely about creating temporary variables all over the place, reading and assigning values. You'd better start to love them. :)
One more remark regarding properties. Although you could technically put a lot of logic there, it is recommended to keep properties simple and try not to use any code that could throw exceptions. A need to call other functions may indicate that this property is better be made a method or that there is some initialization code needed somewhere. Just rethink what you're doing and whether it does really look like a property.
I'm on an ASP.Net 2.0 project, in C#. I have some data that gets stored in session state. For ease of use, it is wrapped in a property, like this:
protected IList<Stuff> RelevantSessionData
{
get
{
return (IList<Stuff>) Session["relevant_key"];
}
set
{
Session["relevant_key"] = value;
}
}
Getting and setting the value works exactly as you'd expect. If I want to clear the value, I just set it to null, and there are no problems. However, in another developer's page, he calls the collection's Clear() method. I thought this would be a bug, but it seems to work, and I don't understand why. It works like so:
Debug.WriteLine(RelevantSessionData.Count); //outputs, say, 3
RelevantSessionData.Clear();
Debug.WriteLine(RelevantSessionData.Count); //outputs 0
Why does this work? My naive expectation would be that the middle line loads the serialized value from session, deserializes into an object, calls Clear() on that object, and then lets the unnamed object fall out of scope. That would be a bug, because the value stored in Session would remain unchanged. But apparently, it's smart enough to instead call the property setter and serialize the newly changed collection back into session.
This makes me a little nervous, because there are places in our legacy code where property setters have side effects, and I don't want those getting called if it's not intended.
Does the property setter always get called in a situation like this? Is something else going on? Or do I completely misunderstand what's happening here?
[Added to explain answer]
It turns out did misunderstand. I knew that objects stored in Session must be serializable, and based on that I made too many assumptions about how the collection behaves internally. I was overthinking.
There is only one instance of the stored object (my IList). Each call to the getter returns a reference to that same instance. So the quoted code above works just as it appears, with no special magic required.
And to answer the title question: No, setters are not called implicitly.
Yes, you are right, this would be a bug if your setter/getters were serializing/deserializing the objects. But this is not the case. Instead you are passing based on reference.
So what's basically happening is that the first line in your example gets the item via the get, and Count is called based on that. Then the seccond line is going out and calling get again, returning the same object, running clear, and then the third line is doing the same as the first.
If you had written your setter/getter something like this, you would have a "bug"
protected IList<Stuff> RelevantSessionData
{
get
{
return (IList<Stuff>) JSON.ConvertFromString(Session["relevant_key"]);
}
set
{
Session["relevant_key"] = JSON.ConvertToString(value);
}
}
In this case, a new object would be created and for each call to the get block. But since your example above is simply passing around the reference to the same object, you're not going to see this "bug".
And I say "bug" since it's not really a bug, it's just more of a misunderstanding of what's happening behind the scenes.
I hope this helps.
Your code is roughly equivalent to:
Debug.WriteLine(((IList<Stuff>) Session["relevant_key"]).Count); //outputs, say, 3
((IList<Stuff>) Session["relevant_key"]).Clear();
Debug.WriteLine(((IList<Stuff>) Session["relevant_key"]).Count); //outputs 0
Even if you only call the getter, you are clearing the collection. So the debug output seems normal.
You can expect property setters to be called if:
The are publicly visible (visible to other assemblies).
They implement the setter as part of an interface visible to other assemblies. In some cases, such as
They are used in WPF binding (but the framework will follow the rules about the BindingMode).
They are used in MEF with the ImportAttribute.
They are used in some other binding framework (you get the idea).
You shouldn't run into problems if, for interfaces defined by others, you meet the pre- and post-conditions of the operation.
Edit: I agree with the above. My first choice for exposing a collection is:
private readonly List<T> _sources = new List<T>();
/* Or ICollection<T>, ReadOnlyCollection<T>, or IList<T>, or
* (only a real option for `internal` types) List<T>
*/
public IEnumerable<T> Sources
{
get
{
return _sources;
}
}
If you absolutely must initialize the list after the object is created, then you can use something like this as the second option:
public IList<T> Sources
{
get;
private set;
}
There are situations where the above practices aren't necessarily the best answer, but these are the two most common (IMO?).