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.
Related
Is there a convention for whether or not to use a property to calculate a value on call? For instance if my class contains a list of integers and I have a property Average, the average will possibly change when an integer is added/removed/modified from the list, does doing something like this:
private int? _ave = null;
public int Average
{
get
{
if (_ave == null )
{
double accum = 0;
foreach (int i in myList)
{
accum += i;
}
_ave = accum / myList.Count;
return (int)_ave;
}
else
{
return (int)_ave;
}
}
}
where _ave is set to null if myList is modified in a way that may change the average...
Have any conventional advantage/disadvantage over a method call to average?
I am basically just wondering what the conventions are for this, as I am creating a class that has specific properties that may only be calculated once. I like the idea of the classes that access these properties to be able to access the property vs. a method (as it seems more readable IMO, to treat something like average as a property rather than a method), but I can see where this might get convoluted, especially in making sure that _ave is set to null appropriately.
The conventions are:
If the call is going to take significantly more time than simply reading a field and copying the value in it, make it a method. Properties should be fast.
If the member represents an action or an ability of the class, make it a method.
If the call to the getter mutates state, make it a method. Properties are invoked automatically in the debugger, and it is extremely confusing to have the debugger introducing mutations in your program as you debug it.
If the call is not robust in the face of being called at unusual times then make it a method. Properties need to continue to work when in used in constructors and finalizers, for example. Again, think about the debugger; if you are debugging a constructor then it should be OK for you to examine a property in the debugger even if it has not actually been initialized yet.
If the call can fail then make it a method. Properties should not throw exceptions.
In your specific case, it is borderline. You are performing a potentially lengthy operation the first time and then caching the result, so the amortized time is likely to be very fast even if the worst-case time is slow. You are mutating state, but again, in quite a non-destructive way. It seems like you could characterize it as a property of a set rather than an "ability" of the set. I would personally be inclined to make this a method but I would not push back very hard if you had a good reason to make it a property.
Regarding your specific implementation: I would be much more inclined to use a 64 bit integer as the accumulator rather than a 64 bit double; the double only has 53 bits of integer precision compared to the 64 bits of a long.
Microsoft's recommendation to using methods:
Use method
If calling has side effects
If it returns different values each calls
If it takes long time to call
If operation requires parameters (except indexers)
Use property if calculated value is attribute of object.
In your case I think property with implicit lazy calculation would be good choice.
Yes there is... a get accessor should not in any way modify the state of the object. The returned value could be calculated of course, and you might have a ton of code in there. But simply accessing a value should not affect the state of the containing instance at all.
In this particular case, why not calculate everything upon construction of the class instance instead? Or provide a dedicated method to force the class to do so.
Now I suppose there might be very specific situations where that sort of behavior is OK. This might be one of those. But without seeing the rest of the code (and the way it is used), it's impossible to tell.
When it comes to designing classes and "communication" between them, I always try to design them in such way that all object construction and composing take place in object constructor. I don't like the idea of object construction and composition taking place from outside, like other objects setting properties and calling methods on my object to initialize it. This especially gets ugly when multiple object try to do thisto your object and you never know in what order your props\methods will be executed.
Unforunatly I stumbl on such situations quite often, especially now with the growing popularity of dependecy injection frameworks, lots of libraries and frameworks rely on some kind of external object initialization, and quite often require not only constructor injection on our object but property injection too.
My question are:
Is it ok to have objects that relly on some method, or property to be called on them after which they can consider them initialzied?
Is ther some kind of pattern for situations when your object acting is receiver, and must support multiple interfaces that call it, and the order of these calls does matter? (something better than setting flags, like ThisWasDone, ThatWasCalled)
Is it ok to have objects that relly on some method, or property to be called on them after which they can consider them initialzied?
No. Init methods are a pain since there is no guarantee that they will get called. A simple solution is to switch to interfaces and use factory or builder pattern to compose the implementation.
#Mark Seemann has written a article about it: http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling.aspx
Is there some kind of pattern for situations when your object acting is receiver, and must support multiple interfaces that call it, and the order of these calls does matter? (something better than setting flags, like ThisWasDone, ThatWasCalled)
Builder pattern.
I think it is OK, but there are implications. If this is an object to be used by others, you need to ensure that an exception is thrown any time a method or property is set or accessed and the initialization should have been called but isn't.
Obviously it is much more convenient and intuitive if you can take care of this in the constructor, then you don't have to implement these checks.
I don't see anything wrong in this. It may be not so convinient, but you can not ALWAYS use initialization in ctor, like you can not alwats drive under green light. These are dicisions that you made based on your app requirements.
It's ok. Immagine if your object, for example, need to read data from TCP stream or a file that ciuld be not present or corrupted. Raise an exception from ctor is baaad.
It's ok. If you think, for example, about some your DSL language compiler, it can looks like:
A) find all global variables and check if there mem allocation sum sutisfies your device requierements
B) parse for errors
C) check for self cycling
And so on...
Hoe this helps.
Answering (1)
Why not? An engine needs the driver because this must enter the key for the car, and later power-on. Will a car do things like detecting current speed if engine is stopeed? Or Will the car show remaining oil without powering-on it?
Some programming goals won't be able to have their actors initialized during its object construction, and this isn't because it's a non-proper way of doing things but because it's the natural, regular and/or semantically-wise way of representing its whole behavior.
Answering (2)
A decent class usage documentation will be your best friend. Like answer to (1), there're some things in this world that should be done in order to get them done rightly, and it's not a problem but a requirement.
Checking objects' state using flags isn't a problem too, it's a good way of adding reliability to your object models, because its own behaviors and consumers of them will be aware about if things got done as expected or not.
First of all, Factory Method.
public class MyClass
{
private MyClass()
{
}
public Create()
{
return new MyClass();
}
}
Second of all, why do you not want another class creating an object for you? (Factory)
public class MyThingFactory
{
IThing CreateThing(Speed speed)
{
if(speed == Speed.Fast)
{
return new FastThing();
}
return new SlowThing();
}
}
Third, why do multiple classes have side effects on new instances of your class? Don't you have declarative control over what other classes have access to your object?
How bad is something like:
public class Test
{
private string pKey = null;
public string Key {
get { return pKey; }
set { if (pKey==null) pKey=value;}
}
}
This would allow me to use XMLSerializer with the class and make sure that Key can't be changed after being initially set.
I agree that my initial idea was bad.
I now know that there is no way to make this using the standard XML Serializer. 'ssg' suggestion won't be serialized because it doesn't have a public setter.
The only choices here are implementing the IXmlSerializable, or using another serialization method, like DataContractSerializer. The problem with the former is that every derivate of the class would also have to implement IXmlSerializable; the problem with the latter is that you can't use attributes or have much control over the generated XML.
Bad, consider:
test.pKey = null;
test.Key = 'my new key';
I've managed to circumvent your protection (obviously you could add a null check to the set method to fix this issue).
The same problem could occur if the deserialized object had a null key, the key could still be set the first time it was accessed... It seems like if you need this sort of protection, you should probably look at another way of getting it.
The XMLSerializer places restrictions on the classes you use with it and by trying to work around those restrictions, you’re likely to cause confusion. If you are a one-man shop and you are the only person that looks at the code, this may be less of an issue (at least until you step away from the code for a coupld of months), however in a multi-developer environment the behaviour of your class is likely to cause confusion. For example, you’re hiding the assignment not working by not throwing an exception, so assignment operations would compile and run, but, not update the object and not throw an exception to indicate the failure (which could lead to some hard to track down bugs).
As some of you have discovered, a new feature (?) appeared WPF 4, where the data binding engine may pass your custom control instances of the class MS.Internal.NamedObject with the name "{DisconnectedItem}" into the DataContext - instead of the data item your code is expecting (this happens when a templated control is disconnected by its ItemsControl). These are called sentinel objects.
In existing code, this can lead to spurious exceptions where the code is unprepared for it. These can be swallowed up by the data binding subsystem, or they can wreak havoc. Keep an eye on your debug console.
Anyway, I learned about this on this MSDN forum. And there's a post by Sam Bent which explains it all. Go read it now, you'll want to know this. The essence is that these events should never have fired (that's the bug), so:
Ignore the DataContextChanged event if
the DataContext is a sentinel object.
So, so I want to check my DataContext. But how? Consider:
public bool IsSentinelObject(object dataContext)
{
return (dataContext is MS.Internal.NamedObject);
}
Guess what happens? It doesn't compile because MS.Internal.NamedObject is internal, and not accessible to me. Of course, I can hack it like this:
public bool IsSentinelObject(object dataContext)
{
return dataContext.GetType().FullName == "MS.Internal.NamedObject"
|| dataContext.ToString() == "{DisconnectedObject}";
}
(or something, which works). I have also followed Sam's suggestion to cache the object for later reference equality checks (it's a singleton).
Of course, this means I don't have a problem, not really. But I'm curious, and this posting will be sure to benefit some users, so it's worth asking anyway:
Is there a way I can exactly check the type against the internal NamedObject type, without resorting to string comparisons?
In .NET 4.5, you can now compare against BindingOperations.DisconnectedSource.
This one?
var disconnectedItem = typeof(System.Windows.Data.BindingExpressionBase)
.GetField("DisconnectedItem", BindingFlags.Static | BindingFlags.NonPublic)
.GetValue(null);
Short Version
For those who don't have the time to read my reasoning for this question below:
Is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters?
Long Version
There are plenty of methods which take objects as parameters, and it doesn't matter whether the method has the object "all to itself" or not. For instance:
var people = new List<Person>();
Person bob = new Person("Bob");
people.Add(bob);
people.Add(new Person("Larry"));
Here the List<Person>.Add method has taken an "existing" Person (Bob) as well as a "new" Person (Larry), and the list contains both items. Bob can be accessed as either bob or people[0]. Larry can be accessed as people[1] and, if desired, cached and accessed as larry (or whatever) thereafter.
OK, fine. But sometimes a method really shouldn't be passed a new object. Take, for example, Array.Sort<T>. The following doesn't make a whole lot of sense:
Array.Sort<int>(new int[] {5, 6, 3, 7, 2, 1});
All the above code does is take a new array, sort it, and then forget it (as its reference count reaches zero after Array.Sort<int> exits and the sorted array will therefore be garbage collected, if I'm not mistaken). So Array.Sort<T> expects an "existing" array as its argument.
There are conceivably other methods which may expect "new" objects (though I would generally think that to have such an expectation would be a design mistake). An imperfect example would be this:
DataTable firstTable = myDataSet.Tables["FirstTable"];
DataTable secondTable = myDataSet.Tables["SecondTable"];
firstTable.Rows.Add(secondTable.Rows[0]);
As I said, this isn't a great example, since DataRowCollection.Add doesn't actually expect a new DataRow, exactly; but it does expect a DataRow that doesn't already belong to a DataTable. So the last line in the code above won't work; it needs to be:
firstTable.ImportRow(secondTable.Rows[0]);
Anyway, this is a lot of setup for my question, which is: is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters, either in its definition (perhaps by some custom attributes I'm not aware of) or within the method itself (perhaps by reflection, though I'd probably shy away from this even if it were available)?
If not, any interesting ideas as to how to possibly accomplish this would be more than welcome. For instance I suppose if there were some way to get the GC's reference count for a given object, you could tell right away at the start of a method whether you've received a new object or not (assuming you're dealing with reference types, of course--which is the only scenario to which this question is relevant anyway).
EDIT:
The longer version gets longer.
All right, suppose I have some method that I want to optionally accept a TextWriter to output its progress or what-have-you:
static void TryDoSomething(TextWriter output) {
// do something...
if (output != null)
output.WriteLine("Did something...");
// do something else...
if (output != null)
output.WriteLine("Did something else...");
// etc. etc.
if (output != null)
// do I call output.Close() or not?
}
static void TryDoSomething() {
TryDoSomething(null);
}
Now, let's consider two different ways I could call this method:
string path = GetFilePath();
using (StreamWriter writer = new StreamWriter(path)) {
TryDoSomething(writer);
// do more things with writer
}
OR:
TryDoSomething(new StreamWriter(path));
Hmm... it would seem that this poses a problem, doesn't it? I've constructed a StreamWriter, which implements IDisposable, but TryDoSomething isn't going to presume to know whether it has exclusive access to its output argument or not. So the object either gets disposed prematurely (in the first case), or doesn't get disposed at all (in the second case).
I'm not saying this would be a great design, necessarily. Perhaps Josh Stodola is right and this is just a bad idea from the start. Anyway, I asked the question mainly because I was just curious if such a thing were possible. Looks like the answer is: not really.
No, basically.
There's really no difference between:
var x = new ...;
Foo(x);
and
Foo(new ...);
and indeed sometimes you might convert between the two for debugging purposes.
Note that in the DataRow/DataTable example, there's an alternative approach though - that DataRow can know its parent as part of its state. That's not the same thing as being "new" or not - you could have a "detach" operation for example. Defining conditions in terms of the genuine hard-and-fast state of the object makes a lot more sense than woolly terms such as "new".
Yes, there is a way to do this.
Sort of.
If you make your parameter a ref parameter, you'll have to have an existing variable as your argument. You can't do something like this:
DoSomething(ref new Customer());
If you do, you'll get the error "A ref or out argument must be an assignable variable."
Of course, using ref has other implications. However, if you're the one writing the method, you don't need to worry about them. As long as you don't reassign the ref parameter inside the method, it won't make any difference whether you use ref or not.
I'm not saying it's good style, necessarily. You shouldn't use ref or out unless you really, really need to and have no other way to do what you're doing. But using ref will make what you want to do work.
No. And if there is some reason that you need to do this, your code has improper architecture.
Short answer - no there isn't
In the vast majority of cases I usually find that the issues that you've listed above don't really matter all that much. When they do you could overload a method so that you can accept something else as a parameter instead of the object you are worried about sharing.
// For example create a method that allows you to do this:
people.Add("Larry");
// Instead of this:
people.Add(new Person("Larry"));
// The new method might look a little like this:
public void Add(string name)
{
Person person = new Person(name);
this.add(person); // This method could be private if neccessary
}
I can think of a way to do this, but I would definitely not recommend this. Just for argument's sake.
What does it mean for an object to be a "new" object? It means there is only one reference keeping it alive. An "existing" object would have more than one reference to it.
With this in mind, look at the following code:
class Program
{
static void Main(string[] args)
{
object o = new object();
Console.WriteLine(IsExistingObject(o));
Console.WriteLine(IsExistingObject(new object()));
o.ToString(); // Just something to simulate further usage of o. If we didn't do this, in a release build, o would be collected by the GC.Collect call in IsExistingObject. (not in a Debug build)
}
public static bool IsExistingObject(object o)
{
var oRef = new WeakReference(o);
#if DEBUG
o = null; // In Debug, we need to set o to null. This is not necessary in a release build.
#endif
GC.Collect();
GC.WaitForPendingFinalizers();
return oRef.IsAlive;
}
}
This prints True on the first line, False on the second.
But again, please do not use this in your code.
Let me rewrite your question to something shorter.
Is there any way, in my method, which takes an object as an argument, to know if this object will ever be used outside of my method?
And the short answer to that is: No.
Let me venture an opinion at this point: There should not be any such mechanism either.
This would complicate method calls all over the place.
If there was a method where I could, in a method call, tell if the object I'm given would really be used or not, then it's a signal to me, as a developer of that method, to take that into account.
Basically, you'd see this type of code all over the place (hypothetical, since it isn't available/supported:)
if (ReferenceCount(obj) == 1) return; // only reference is the one we have
My opinion is this: If the code that calls your method isn't going to use the object for anything, and there are no side-effects outside of modifying the object, then that code should not exist to begin with.
It's like code that looks like this:
1 + 2;
What does this code do? Well, depending on the C/C++ compiler, it might compile into something that evaluates 1+2. But then what, where is the result stored? Do you use it for anything? No? Then why is that code part of your source code to begin with?
Of course, you could argue that the code is actually a+b;, and the purpose is to ensure that the evaluation of a+b isn't going to throw an exception denoting overflow, but such a case is so diminishingly rare that a special case for it would just mask real problems, and it would be really simple to fix by just assigning it to a temporary variable.
In any case, for any feature in any programming language and/or runtime and/or environment, where a feature isn't available, the reasons for why it isn't available are:
It wasn't designed properly
It wasn't specified properly
It wasn't implemented properly
It wasn't tested properly
It wasn't documented properly
It wasn't prioritized above competing features
All of these are required to get a feature to appear in version X of application Y, be it C# 4.0 or MS Works 7.0.
Nope, there's no way of knowing.
All that gets passed in is the object reference. Whether it is 'newed' in-situ, or is sourced from an array, the method in question has no way of knowing how the parameters being passed in have been instantiated and/or where.
One way to know if an object passed to a function (or a method) has been created right before the call to the function/method is that the object has a property that is initialized with the timestamp passed from a system function; in that way, looking at that property, it would be possible to resolve the problem.
Frankly, I would not use such method because
I don't see any reason why the code should now if the passed parameter is an object right created, or if it has been created in a different moment.
The method I suggest depends from a system function that in some systems could not be present, or that could be less reliable.
With the modern CPUs, which are a way faster than the CPUs used 10 years ago, there could be the problem to use the right value for the threshold value to decide when an object has been freshly created, or not.
The other solution would be to use an object property that is set to a a value from the object creator, and that is set to a different value from all the methods of the object.
In this case the problem would be to forget to add the code to change that property in each method.
Once again I would ask to myself "Is there a really need to do this?".
As a possible partial solution if you only wanted one of an object to be consumed by a method maybe you could look at a Singleton. In this way the method in question could not create another instance if it existed already.