I'm working in .net 3.5.
I have a class "A" which has a stack and a getter property which, when called, removes the first item in the stack and retrieves the next one.
After initializing the class, I saw that the getter works without being called, and removes the top item in the stack, thus giving me bad results. A breakpoint in the getter did not show anyone passing through it.
When I change the property to a function, the stack is returned ok.
I'd be happy if someone could explain why is that.
Here is the simplified class:
public class A
{
private Stack<string> Urls;
public A(string title, string[] array)
{
Urls = new Stack<string>();
foreach (string s in array)
{
Urls.Push(s);
}
}
public string Url
{
get { return Urls.Peek(); }
}
public string NextUrl
{
get{
if (Urls.Count > 1)
{ Urls.Pop(); }
return Urls.Peek();
};
}
}
Firstly, making a property accessor change the state is generally a bad idea. The most it should do is lazily initialize something - or possibly give a volatile value (like DateTime.Now does).
Secondly, you're probably seeing this if you're running under the debugger - it accesses properties while you're stepping through code. That would probably explain why the breakpoint wasn't being hit, too.
Urls.Pop();
wants to be
return Urls.Pop();
as it returns the value and removes it from the list at the same time
Actually having re-read your question, it looks like it is because the debugger evaluates properties. If you run the application without the debugger do you get the same problem?
This is bad design I think. A get accessor should not mutate the object in a way that causes different results on subsequent calls.
IMO, the problem here is having a property that has non-obvious side-effects; this should be a method:
public string GetNextUrl() { /* */ }
Otherwise bad things happen everywhere (the debugger, data-binding, etc). Don't assume that somebody only reads a property once.
The only sensible use of side-effects in properties is things like lazy-loading, deferred initialization, etc. It should still report the same value when called sequentially without any other obvious mutating calls.
Related
Imaginge this class
Class Person
{
public string Name { get; set; }
public int SomeExpensiveCalculation {
get {
return TimeConsumingCalulation(Name )
}
}
}
Since get is a method, I assume, when the the property "SomeExpensiveCalculation" is never requested or used, the function "TimeConsumingCalulation" is never executed. Is this correct?
That's correct. Property getter is just a method that executes when called.
But properties should be simple, avoid expensive calculations inside the property get.
That is correct. Properties are just Syntax Sugar for GetValue and SetValue function pairs. I think they also had some added reflection support.
With Time Consuming Operation for a value that may not be needed, maybe a Lazy[T] would be a good tool? It might at least be clearer that Lazy Initialsiation is your intention. Between it and WeakRefrence[T], you can usually cover edge cases with Memory allocation or time consumption.
However wich code is actually executed at runtime is a bit tricky. .NET has this Feature called a "just in time" compiler, and it may or may not do all kinds of Optimsiations. It can add a temporary variable to avoid retrieving the same collection value twice. Or cut unused temporary variables. Cut out a large part of the bounds checks in a array accessor.
Inling properties is way up there, but usually this will not affect any working of it.
I have a class PluginProvider that is using a PluginLoader component to load plugins (managed/native) from the file system. Within the PluginProvider class, there is currently defined a property called 'PluginTypes' which calls the 'InitializePlugins' instance method on get().
class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
//isInitialized is set inside InitializePlugins method
if(!isInitialized)
{
InitializePlugins(); //contains thread safe code
}
//_pluginTypes is set within InitializePlugins method
return _pluginTypes;
}
}
}
I am looking at refactoring this piece of code. I want to know whether this kind of initialization is fine to do within a property. I know that heavy operations must not be done in a property. But when i checked this link : http://msdn.microsoft.com/en-us/library/vstudio/ms229054.aspx , found this " In particular, operations that access the network or the file system (other than once for initialization) should most likely be methods, not properties.". Now I am a bit confused. Please help.
If you want to delay the initialization as much as you can and you don't know when your property (or properties) will be called, what you're doing is fine.
If you want to delay and you have control over when your property will be called the first time, then you might want to make your method InitializePlugins() public and call it explicitly before accessing the property. This option also opens up the possibility of initializing asynchronously. For example, you could have an InitializePluginsAsync()that returns a Task.
If delaying the initialization is not a big concern, then just perform the initialization within the constructor.
This is of course a matter of taste. But what i would do depends on the length of the operation you're trying to perform. If it takes time to load the plugins, i would create a public method which any user would need to call before working with the class. A different approach would be to put the method inside the constructor, but IMO constructors should return as quickly as possible and should contain field / property initialization.
class PluginProvider
{
private bool _isInitialized;
IEnumerable<IPluginType> PluginTypes { get; set;}
public void Initialize()
{
if (_isInitialized)
{
return;
}
InitializePlugins();
_isInitialized = true;
}
}
Note the down side of this is that you will have to make sure the Initialize method was called before consuimg any operation.
Another thing that just came to mind backing this approach is exception handling. Im sure you wouldn't want your constructorcto be throwing any kind of IOException in case it couldn't load the types from the file system.
Any initialization type of code should be done in the constructor, that way you know it will be called once and only once.
public class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
return _pluginTypes;
}
}
public PluginProvider()
{
InitializePlugins();
}
}
What you are doing there is called lazy initialization. You are postponing doing a potentially costly operation until the very moment its output is needed.
Now, this is not an absolute rule. If your InitializePlugins method takes a long time to complete and it might impact user experience, then you can consider moving it into a public method or even making it asynchronous and call it outside of the property: at app startup or whenever you find a good moment to call a long-lasting operation.
Otherwise, if it's a short lived one-time thing it can stay there. As I said, not an absolute rule. Generally these are some guidelines for whatever applies to a particular case.
My question may be a part of an old topic - "properties vs fields".
I have situation where variable is read-only for outside class but needs to be modified inside a class. I can approach it in 2 ways:
First:
private Type m_Field;
public Type MyProperty { get { return m_Field; } }
Second:
public Type MyProperty { get; private set; }
After reading several articles (that mostly covered benefits of using public properties instead of public fields) I did not get idea if the second method has some advantage over the first one but writing less code. I am interested which one will be better practice to use in projects (and why) or it's just a personal choice.
Maybe this question does not belong to SO so I apologize in advance.
The second version produces less clutter, but is less flexible. I suggest you use the second version until you run into a situation that makes the first version necessary and then refactor - changes will be local to the class anyway, so don't worry too much about that!
Generally, writing less code is a good idea. The less code you write, the less bugs you produce :)
Second version is shorter, so I think it's usually better.
The exception is, when the only write access occurs in the constructor. Then I prefer the first version as this allows the field to be marked as readonly.
The second one will pretty much compile down to the first one anyway, so IMO always use the second as it's less & neater code.
The only scenarios I tend to use the first approach are when I want to lazily load a property e.g.
private List<string> _items;
...
public List<string> Items
{
get
{
if (_items == null)
{
_items = new List<string>();
// load items
}
return _items;
}
}
Please go through the following question. IT seems like same ,
https://softwareengineering.stackexchange.com/questions/72495/net-properties-use-private-set-or-readonly-property
For debugging the second is the best. Otherwise you'll have to put breakpoins at each place where you set the field. With the second you put one breakpoint on the set of the property.
Personally I prefer the second version because it is less to write so I can use the time to do more complex coding.... plus in my opinion it promotes lazy development
In existing code of my project, at number of places the property is declared like this:
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
if (this.resourceID != value)
{
this.resourceID = value;
}
}
}
Note: private long resourceID is already declared.
Properties not only of value types but also of reference types (including string) too are declared like this.
Another example:
public Collection<Ability> Abilities
{
get
{
return this.abilities;
}
set
{
if (value == null)
{
throw new ArgumentNullException("Abilities");
}
this.abilities = value;
}
}
As per my knowledge, the setter in the first example does not make any sense and the if condition is meaningless there. So i decided to change the code (as part of refactoring) to make them Auto-Properties. (In second example I need setter since exception is handled there.)
I want to know from experts here, will whether making existing properties auto properties (or at least removing if condition from setter) cause any harm? Sometimes there are subtle things which a developer may not be aware of and some changes can have side effects too. That's why I am asking this question. (My libraries are used at many places.)
Note: Let me know if this is purely a homework question.
Converting:
private long resourceID;
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
this.resourceID = value;
}
}
into:
public long ResourceID { get; set; }
won't cause any harm, guaranteed.
Removing the if statement might cause harm. For example in WPF when working with the MVVM pattern and implementing the INotifyPropertyChanged interface it is often good practice to check whether the value has changed before actually setting it. Removing this check will provoke notifications to be sent to the UI no matter whether the value changed or not. So it would be a breaking change.
I can only think of one kind of problem you could run into (which is fixable):
If you are using ORM or other external tool, they might rely on a naming convention for finding properties/fields. So, the 3rd party dll might be looking for a field resourceId that no longer exists.
So, code using reflection to access fields might break, but if you have control over the codebase, that is unlikely to be an issue.
There are some edge-cases where this might cause harm:
Changing to an automatically implemented property {get;set;}
if you are using field-based serialization at any point (for example, BinaryFormatter), then this will break when changing to an automatically implemented property, as the field-name will change. This will also impact any other scenario that uses reflection to access the (hopefully private) fields, but BinaryFormatter is the most common cause of confusion here.
Removing the if test
will be fine for most data-types such as long etc, however, if you use it with a type that implements a custom equality operation, you might find you are suddenly swapping a reference when previously (with the if) the objects reported equal for different references
The first is a more likely problem. If you are using BinaryFormatter, then keep the private field (byt maybe remove the if test). And then start refactoring your code away from BinaryFormatter ;p
What you have done is correct. The if statement is meaningless. I always think that less code is better, because the lines of code is directly proportional to the number of faults.
public long ResourceID { get; set; }
Your first example only sets the resourceID field if its value has changed.
The only difference you would see by removing the "if" test is a possible impact if multiple threads are reading the value. In which case they probably should be using a lock, so it's almost certainly safe to remove the test.
Your second example prevents a caller from setting the property value to null. Presumably the field is initialized to a non-null value, and this has value as it means that callers can read the property without needing to check for null.
Usually in such scenarios and how you've explained, it shouldn't be a concern.
You could just go ahead and change the code of all properties;
public long ResourceID { get; set; }
Or
public long ResourceID
{
get { return this.resourceID; }
set { this.resourceID = value; }
}
But it might cause an issue if upon
changing the value of the property,
it cascades to some other custom
function-call which is only executed
if the new value is different from
old ones. Usually when when you've implemented custom events or even maybe in case of property-changed events
Also might affect, when using
Data-Context classes
Both scenarios are totally application specific.
I'd suggest you reactor with caution. Or as you've written yourself, HOMEWORK.
Let's have an object created in a getter like this :
public class Class1
{
public string Id { get; set; }
public string Oz { get; set; }
public string Poznamka { get; set; }
public Object object
{
get
{
// maybe some more code
return new Object { Id = Id, poznamla = Poznamka, Oz = OZ };
}
}
}
Or should I rather create a Method that will create and return the object ?
Yes, it is bad practice.
Ideally, a getter should not be changing or creating anything (aside from lazy loading, and even then I think it leads to less clear code...). That way you minimise the risk of unintentional side effects.
Properties look like fields but they are methods. This has been known to cause a phenomenal amount of confusion. When a programmer sees code that appears to be accessing a field, there are many assumptions that the programmer makes that may not be true for a property.So there are some common properties design guidelines.
Avoid returning different values from the property getter. If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time.
A property method may require additional memory or return a reference to something that is not actually part of the object's state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object's state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.
Consider that a property cannot be passed as an out or ref parameter to a method; a field can.
Avoid long running property getters. A property method can take a long time to execute; field access always completes immediately.
Avoid throwing exceptions from getters.
Do preserve previous values if a property setter throws an exception
Avoid observable side effects.
Allow properties to be set in any order even if this results in a temporary invalid state of objects.
Sources
"CLR via C#", Jeffrey Richter. Chapter 9. Defining Properties Intelligently
"Framework Design Guidelines" 2nd edition, Brad Abrams, Krzysztof Cwalina, Chapter 5.2 Property Design
If you want your getter to create a new object every time it is accessed, that's the way to do it. This pattern is normally refered to as a Factory Method.
However, this is not normally needed on properties (ie. getters and setters), and as such is considered bad practice.
yes, it is ... from the outside, it should be transparent, whether you access a property or a field ...
when reading twice from field, or a property, you expect two things:
there is no impact on the object's (external) behaviour
you get identical results
I have no real knowledge of C#, but I hope, the following makes my point clear. let's start like this:
Object o1 = myInst.object;
Object o2 = myInst.object;
o1.poznamka = "some note";
in the case of a field, conditions like the following will be true:
o1 == o2;
o2.poznamka == "some note";
if you use a property with a getter, that returns a new object every time called, both conditions will be false ...
your getter seems to be meant to produce a temporary snapshot of your instance ... if that is what you want to do, than make it a plain method ... it avoids any ambiguities ...
A property should, to all intents and purposes, act like a field. That means no exceptions should be thrown, and no new objects should be created (so you don't create lots of unneccessary objects if the property is used in a loop)
Use a wrapper class or similar instead.
According to me if something is 'property' the getter should return you a property (basically a data that is already existing) relevant to the object.
In your case, you are returning something that is not a property of that object at that moment. You are not returning a property of your object but a product of some action.
I would go with a method something like GetMyObject() instead. Especially if there is an 'action' will take place, I think it is most of the time best to have a method than a property name.
And try to imagine what would other developers who are not familiar with your code expect after seeing your property.
A property is just a convenient way to express a calculated field.
It should still represent something about an object, regardless of how the value itself is arrived at. For example, if the object in question is an invoice, you might have to add up the cost of each line item, and return the total.
What's written in the question breaks that rule, because returning a copy of the object isn't something that describes the object. If the return value changes between calls to the property without an explicit change of object state, then the object model is broken.
Speaking in generalities, returning a new object like this will just about always break the rule (I can't think of a counter-example right now), so I would say that it's bad practice.
There's also the gotcha of properties where you can so easily and innocently call on a property multiple times and end up running the same code (which hopefully isn't slow!).
For writing code that is easily tested, you have to maintain separation of Object initialization.
i.e while in test cases you do not have hold on test some specific items.
like in House object you dont want to test anything related to kitchen object.
and you wana test only the garden. so while you initiate a house class and initiate object in some constructors or in getters you wont be coding good that will support testing.
As an aside to the comments already made, you can run into some real debugging headaches when lazy loading fields via a property.
I had a class with
private Collection<int> moo;
public Collection<int> Moo
{
get
{
if (this.moo == null) this.moo = new Collection<int>();
return this.moo;
}
}
Then somewhere else in the class there was a public method that referenced
this.moo.Add(baa);
without checking it was instantiated.
It threw a null reference exception, as expected. But the exception was on a UI thread so not immediately obvious where it was coming from. I started tracing through, and everytime I traced through, the error dissapeared.
For a while I have to admit I thought I was going crazy. Debugger - no error. Runtime, error. Much scratching of head later I spotted the error, and realised that the Visual Studio debugger was instantiating the Collection as it displayed the public properties of the class.
It's maybe at most acceptable for structs. For reference types, I would only create a new object in a getter when it's only done once using some lazy-load pattern.
It depends on the use of the getter. It's a great place to include this kind of code for lazy loading.
It is a bad practice. In your example, you should be able to expect the same Object every time you access the object property.
As you have it it is bad but not dis similar to an acceptable practice called lazy loading which can be read about here.
http://www.aspcode.net/Lazy-loading-of-structures-in-C-howto-part-8.aspx
It is a bad practice. But if you are thinking of objects as a bunch of getters & setters you should check the classical discussions about the topic.
As some folks mentioned, lazy loading could be a reason to do so. Depends on the actual business logic you are modeling here. You should create a separate method if it is better for legibility purposes, but if the code to create the object is simple you could avoid the indirection.