C# can I lock a method parameter? - c#

We have a class variable ArrayList binaryScanData in a class. In all methods having access to it, we put lock(binaryScanData) on it because it is shared. Now we want to move one of those methods out to another util class to make it a static method. We will pass that binaryScanData into the method like this:
public static void convertAndSaveRawData(ref MemoryStream output, ref ArrayList binaryScanData)
Our questions are followed:
how can we sychoronize that binaryScanData? can we do the same as it is originally?
ref is necessary? It will only be read in that convertAndSaveRawData method.

The ref isn't necessary, it is only needed if you are going to change the reference itself (ie, assign a new list to it). You can still lock on the object if you like. I recommend locking on SyncRoot, which I'm not sure if ArrayList has. If not, you might consider moving up to List<T>.

You don't need to make it a ref parameter unless you write binaryScanData = something.
You can lock on the parameter the same way you lock on anything else.
The C# lock keyowrd locks on an object instance; it doesn't matter what the instance came from.

This sounds very wrong. I can imagine that your class objects share a single ArrayList instance and that therefore code that accesses it needs to be synchronized. But that would make the ArrayList object reference static as well, why do you have to pass it as an argument?
If other code needs to call this static method without having to use a reference to your class object then they'd probably have to pass their own instance of the ArrayList. Then it doesn't make sense anymore that you would need to lock. The calling code needs to take care of locking. Only it knows in what other places that particular ArrayList object gets used.
Sorry, I can't make much sense of it. That starts by you using the ArrayList object as the lock argument. You can't lock data, you can only lock code that uses data.

how can we sychoronize that binaryScanData? can we do the same as it is originally?
By locking the same object instance from every piece of code that requires synchronization.
Note that this does not necessarily imply locking the same object you're modifying. In fact, that's dangerous and considered bad practice. It leaves you susceptible to deadlocks and other nastiness because some other code could lock the same object. You're best off creating your own, private object and using that for synchronization.
ref is necessary? It will only be read in that convertAndSaveRawData method.
No, it's not. You've got two entirely different concepts mixed up.

You can create a synchronized wrapper to an existing ArrayList that internally locks on all get/sets:
ArrayList unsyncList = new ArrayList();
ArrayList syncWrapperList = ArrayList.Synchronized(unsyncList);
There is a perf cost to the locking, so only use the wrapper where you must synchronize every call.

ref isn't needed for either parameter as both will be passed by reference anyway, as they are reference types.
As has been pointed out, ArrayList is not recommended as a way of holding a list of items anymore, as it often requires boxing and is therefore usually a lot slower. Try List<T> instead unless you are using 1.1
Those two points don't answer you're main question though: to synchronise a list is not a trivial task, as the .NET implementation is not thread safe. You can see a whole discussion on it: Why is C# List<> not thread-safe? You can synchronise the list inside your own class, but it could still be altered outside of that class.
One technique, if you have created the list yourself, is to make it a read-only list, and provide methods to add to it by subclassing List<T> or IList<T>.
This ThreadSafe List article attempts to make a generic thread-safe list, but if you read the comments at the bottom of the page it still has shortcomings.

Related

Why structs cannot have destructors?

What is best answer on interview on such question you think?
I think I didn't find a copy of this here, if there is one please link it.
Another way of looking at this - rather than just quoting the spec which says that structs can't/don't have destructors - consider what would happen if the spec was changed so that they did - or rather, let's ask the question: can we guess why did the language designers decide to not allow structs to have 'destructors' in the first place?
(Don't get hung up on the word 'destructor' here; we're basically talking about a magic method on structs that gets called automatically when the variable goes out of scope. In other words, a language feature analogous to C++'s destructors.)
The first thing to realize is that we don't care about releasing memory. Whether the object is on the stack or on the heap (eg. a struct in a class), the memory will be taken care of one way or another sooner or later; either by being popped off the stack or by being collected. The real reason for having something that's destructor-like in the first place is for managing external resources - things like file handles, window handles, or other things that need special handling to get them cleaned up that the CLR itself doesn't know about.
Now supposed you allow a struct to have a destructor that can do this cleanup. Fine. Until you realize that when structs are passed as parameters, they get passed by value: they are copied. Now you've got two structs with the same internal fields, and they're both going to attempt to clean up the same object. One will happen first, and so code that is using the other one afterwards will start to fail mysteriously... and then its own cleanup will fail (hopefully! - worst case is it might succeed in cleaning up some other random resource - this can happen in situations where handle values are reused, for example.)
You could conceivably make a special case for structs that are parameters so that their 'destructors' don't run (but be careful - you now need to remember that when calling a function, it's always the outer one that 'owns' the actual resource - so now some structs are subtly different to others...) - but then you still have this problem with regular struct variables, where one can be assigned to another, making a copy.
You could perhaps work around this by adding a special mechanism to assignment operations that somehow allows the new struct to negotiate ownership of the underlying resource with its new copy - perhaps they share it or transfer ownership outright from the old to the new - but now you've essentially headed off into C++-land, where you need copy constructors, assignment operators, and have added a bunch of subtleties waiting to trap the unaware novice programmer. And keep in mind that the entire point of C# is to avoid that type of C++-style complexity as much as possible.
And, just to make things a bit more confusing, as one of the other answers pointed out, structs don't just exist as local objects. With locals, scope is nice and well defined; but structs can also be members of a class object. When should the 'destructor' get called in that case? Sure, you can do it when the container class is finalized; but now you have a mechanism that behaves very differently depending on where the struct lives: if the struct is a local, it gets triggered immediately at end of scope; if the struct is within a class, it gets triggered lazily... So if you really care about ensuring that some resource in one of your structs is cleaned up at a certain time, and if your struct could end up as a member of a class, you'd probably need something explicit like IDisposable/using() anyhow to ensure you've got your bases covered.
So while I can't claim to speak for the language designers, I can make a pretty good guess that one reason they decided not to include such a feature is because it would be a can of worms, and they wanted to keep C# reasonably simple.
From Jon Jagger:
"A struct cannot have a destructor. A destructor is just an override of object.Finalize in disguise, and structs, being value types, are not subject to garbage collection."
Every object other than arrays and strings is stored on the heap in the same way: a header which gives information about the "object-related" properties (its type, whether it's used by any active monitor locks, whether it has a non-suppressed Finalize method, etc.), and its data (meaning the contents of all the type's instance fields (public, private, and protected intermixed, with base-class fields appearing before derived-type fields). Because every heap object has a header, the system can take a reference to any object and know what it is, and what the garbage-collector is supposed to do with it. If the system has a list of all objects which have been created and have a Finalize method, it can examine every object in the list, see if its Finalize method is unsuppressed, and act on it appropriately.
Structs are stored without any header; a struct like Point with two integer fields is simply stored as two integers. While it is possible to have a ref to a struct (such a thing is created when a struct is passed as a ref parameter), the code that uses the ref has to know what type of struct the ref points to, since neither the ref nor the struct itself holds that information. Further, heap objects may only be created by the garbage-collector, which will guarantee that any object which is created will always exist until the next GC cycle. By contrast, user code can create and destroy structs by itself (often on the stack); if code creates a struct along with a ref to it, and passes that ref it to a called routine, there's no way that code can destroy the struct (or do anything at all, for that matter) until the called routine returns, so the struct is guaranteed to exist at least until the called routine exits. On the other hand, once the called routine exits, the ref it was given should be presumed invalid, since the caller would be free to destroy the struct at any time thereafter.
Becuase by definition destructors are used to destruct instances of classes, and structs are value types.
Ref: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
By Microsoft's own words: "Destructors are used to destruct instances of classes." so it's a little silly to ask "Why can't you use a destructor on (something that is not a class)?" ^^

Threading: Locking Under the hood of

What happens when we use the lock object? I am aware that it the runtime makes use of the monitor.Enter and Exit methods. But what really happens under the hood?
Why only reference types to be used for locking?
Even though the object used for accomplishing the locking is changed, how come it still provides thread safety?
In the current sample, we are modifying the object which is used for the locking purpose. Ideally, this is not a preferred way of doing it and best practise is to used a dedicated privately scoped variable.
static List<string> stringList = new List<string>();
static void AddItems(object o)
{
for (int i = 0; i < 100; i++)
{
lock (stringList)
{
Thread.Sleep(20);
stringList.Add(string.Format("Thread-{0},No-{1}", Thread.CurrentThread.ManagedThreadId, i));
}
}
string[] listArray = null;
lock(stringList)
listArray = stringList.ToArray();
foreach (string s in listArray)
{
Console.WriteLine(s);
}
}
What happens under the hood is approximately this:
Imagine the object type has a hidden field in it.
Monitor.Enter() and Monitor.Exit() use that field to communicate with each other.
Every reference type inherits that field from object.
Of course, the type of that field is something special: It’s a synchronization lock that works in a thread-safe manner. In reality, of course, it is not really a field in the CLR sense, but a special feature of the CLR that uses a chunk of memory within each object’s memory to implement that synchronization lock. (The exact implementation is described in “Safe Thread Synchronization” in the MSDN Magazine.)
How come it still provides thread safety? I think what you mean is: why doesn’t it break thread safety for objects that are thread safe? The answer is easy: because you can have objects that are partly thread safe and partly not. You could have an object with two methods, and using one of them is thread safe while the other isn’t. Monitor.Enter() is thread safe irrespective of what the rest of the object does.
Why only reference types to be used for locking? Because only reference types actually have this special magic in their memory chunk. Value types are really literally just the value itself: a 32-bit integer in the case of int; a concatenation of all the fields in the case of a custom struct. You can pass a value type into Monitor.Enter(), and it won’t complain, but it won’t work because the value type will be boxed — i.e., wrapped into an object of a reference type. When you call Monitor.Exit(), it will be boxed again, so it will try to release the lock on a different object reference.
Regarding your code sample: I see nothing wrong with it. All your access to the stringList variable is wrapped in a lock, and you never assign to the stringList field itself except during initialisation. There is nothing that can go wrong with this; it is thread safe. (Of course something could go wrong if some other code accesses the field without locking it. If you were to make the field public, there is a very great chance of that happening accidentally. There is no need to use only locally-scoped variables for such a lock unless you really can’t ensure otherwise that the variable won’t be accessed by code you don’t control.)
But what really happens under the
hood?
Refer to this MSDN article for an in-depth description.
Essentially, each CLR object that gets allocated has an associated field that holds a sync block index. This index points into a pool of sync blocks that the CLR maintains. A sync block holds the same information as a critical section which gets used during synchronization. Initially, an object's sync block index is meaningless (uninitialized). When you lock on the object, however, it gets a valid index into the pool.
Why only reference types to be used
for locking?
You need a reference type since value types don't have the associated sync block index field (less overhead).
Even though the object used for
accomplishing the locking is changed,
how come it still provides thread
safety?
Locking on a CLR object and then modifying it is akin to having a C++ object with a CRITICAL_SECTION member that's used for locking while that same object is modified. There are no thread safety issues there.
In the current sample, we are
modifying the object which is used for
the locking purpose. Ideally, this is
not a preferred way of doing it and
best practise is to used a dedicated
privately scoped variable.
Correct, this situation is also described in the article. If you're not using a privately scoped variable that is in complete control of the owning class, then you can run into deadlock issues when two separate classes decide to lock on the same referenced object (e.g. if for some reason your stringList gets passed to another class that then decides to lock on it as well). This is unlikely, but if you use a strictly-controlled, privately scoped variable that never gets passed around, you will avoid such deadlocks altogether.

What happens when you create an instance of an object containing no state in C#?

I am I think ok at algorithmic programming, if that is the right term? I used to play with turbo pascal and 8086 assembly language back in the 1980s as a hobby. But only very small projects and I haven't really done any programming in the 20ish years since then. So I am struggling for understanding like a drowning swimmer.
So maybe this is a very niave question or I'm just making no sense at all, but say I have an object kind of like this:
class Something : IDoer
{
void Do(ISomethingElse x)
{
x.DoWhatEverYouWant(42);
}
}
And then I do
var Thing1 = new Something();
var Thing2 = new Something();
Thing1.Do(blah);
Thing2.Do(blah);
does Thing1 = Thing2? does "new Something()" create anything? Or is it not much different different from having a static class, except I can pass it around and swap it out etc.
Is the "Do" procedure in the same location in memory for both the Thing1(blah) and Thing2(blah) objects? I mean when executing it, does it mean there are two Something.Do procedures or just one?
They are two separate objects; they just don't have state.
Consider this code:
var obj1 = new object();
var obj2 = new object();
Console.WriteLine(object.ReferenceEquals(obj1, obj2));
It will output False.
Just because an object has no state doesn't mean it doesn't get allocated just like any other object. It just takes very little space (just like an object).
In response to the last part of your question: there is only one Do method. Methods are not stored per instance but rather per class. If you think about it, it would be extremely wasteful to store them per instance. Every method call to Do on a Something object is really the same set of instructions; all that differs between calls from different objects is the state of the underlying object (if the Something class had any state to begin with, that is).
What this means is that instance methods on class objects are really behaviorally the same as static methods.
You might think of it as if all instance-level methods were secretly translated as follows (I'm not saying this is strictly true, just that you could think of it this way and it does kind of make sense):
// appears to be instance-specific, so you might think
// it would be stored for every instance
public void Do() {
Do(this);
}
// is clearly static, so it is much clearer it only needs
// to be stored in one place
private static Do(Something instance) {
// do whatever Do does
}
Interesting side note: the above hypothetical "translation" explains pretty much exactly how extension methods work: they are static methods, but by qualifying their first parameter with the this keyword, they suddenly look like instance methods.
There are most definitely two different objects in memory. Each object will consume 8 bytes on the heap (at least on 32-bit systems); 4 for the syncblock and 4 for the type handle (which includes the method table). Other than the system-defined state data there is no other user-defined state data in your case.
There is a single instance of the code for the Something.Do method. The type handle pointer that each object holds is how the CLR locates the different methods for the class. So even though there are two different objects in memory they both execute the same code. Since Something.Do was declared as an instance method it will have a this pointer passed to it internally so that the code can modify the correct instance members depending on which object was invoking the method. In your case the Something class has no instance members (and thus no user-defined state) and so this is quite irrelevant, but still happens nevertheless.
No they are not the same. They are two separate instances of the class Something. They happen to be identically instantiated, that is all.
You would create 2 "empty" objects, there would be a small allocation on the heap for each object.
But the "Do" method is always in the same place, that has nothing to do with the absence of state. Code is not stored 'in' a class/object. There is only 1 piece of code corresponding to Do() and it has a 'hidden' parameter this that points to the instance of Something it was called on.
Conceptually, Thing1 and Thing2 are different objects, but there is only one Something.Do procedure.
The .Net runtime allocates a little bit of memory to each of the objects you create - one chunk to Thing1 and another to Thing2. The purpose of this chunk of memory is to store (1) the state of the object and (2) a the address of any procedures that that belong to the object. I know you don't have any state, but the runtime doesn't care - it still keeps two separate references to two separate chunks of memory.
Now, your "Do" method is the same for both Thing1 and Thing2, do the runtime only keeps one version of the procedure in memory.
he memory allocated Thing1 includes the address of the the Do method. When you invoke the Do method on Thing1, it looks up the address of its Do method for Thing1 and runs the method. The same thing happens with the other object, Thing2. Although the objects are different, the same Do method is called for both Thing1 and Thing2.
What this boils down to is that Thing1 and Thing2 are different, in that the names "Thing1" and "Thing2" refer to different areas of memory. The contents of this memory is he same in both cases - a single address that points to the "Do" method.
Well, that's the theory, anyway. Under the hood, there might be some kind of optimisation going on (See http://www.wrox.com/WileyCDA/Section/CLR-Method-Call-Internals.id-291453.html if you're interested), but for most practical purposes, what I have said is the way things work.
Thing1 != Thing2
These are two different objects in memory.
The Do method code is in the same place for both objects. There is no need to store two different copies of the method.
Each reference type (Thing1, Thing2) is pointing to a different physical address in main memory, as they have been instantiated separately. The thing pointed to in memory is the bytes used by the object, whether it has a state or not (it always has a state, but whether it has a declared/initialised state).
If you assigned a reference type to another reference type (Thing2 = Thing1;) then it would be the same portion of memory used by two different reference types, and no new instantiation would take place.
A good way of think of the new constructor(), is that you are really just calling the method inside your class whos sole responsibility is to produce you a new instance of an object that is cookie cutted from your class.
so now you can have multiple instances of the same class running around at runtime handling all sorts of situations :D
as far as the CLR, you are getting infact 2 seperate instances on memory that each contain pointers to it, it is very similar to any other OOP language but we do not have to actually interact with the pointers, they are translated the same as a non reference type, so we dont have to worry about them!
(there are pointers in C# if you wish to whip out your [unsafe] keyword!)

Is it OK to lock on System.Collections.Generic.List<t>?

I have been reading about the syncroot element but I can't find it in the List type.
So how should the multithreading synchronization be done with the System.Collections.Generic.List<> type?
The reason you can't find it is because it was explicitly removed. If it is really what you want to do, use a SynchronizedCollection<T> or create a dedicated synchronization object. The best approach (in general) is to create a dedicated synchronization object, as Winston illustrates.
The essential problem with the SyncRoot property is that it provides a false sense of security -- it only handles a very narrow set of circumstances. Developers often neglect synchronization for an entire logical operation, assuming that locking on SyncRoot is good enough.
You generally want to avoid locking on a type (List<T> in this case). If, for example, you have two instances of your type, or another type were to also use a lock on List<T>, they would all competing for a single global lock. Really, what you are trying to achieve is proper synchronization for a single object.
Why do you want to lock on List<T> as opposed to your specific instance of a list?
It is often suggested that the best method of locking is to lock on a private object created solely for that purpose.
private readonly object myListLock = new object();
// Everywhere you access myList
lock(myListLock)
{
// do stuff with myList
}
For a great guide to threading in C#, see this Free E-Book (Threading in C#) by Joe Albahari.
You have to cast the generic list to an ICollection like this:
using System.Collection; // required for ICollection
using System.Collection.Generic;
List<int> myIntList = new List<int>();
lock (((ICollection)myIntList).SyncRoot)
{
// do your synchronized stuff here...
}
Keep in mind that this only synchronizes access to the elements of the generic list. It does not synchronize access to the generic list variable, e.g., myIntList. If you replace myIntList with a new list at some point, using SyncRoot will not be sufficient. In that case, I would recommend creating a specific synchronization object that can be used for both synchronization scenarios.
The answer is Yes, you can use an instance of the list as a synchronizing object:
private readonly List<string> list = new List<string>();
lock(list)
{
// ...
}
So you don't have to use SyncRoot property. Moreover, documentation states that
For collections whose underlying store is not publicly available, the
expected implementation is to return the current instance.
i.e. in some cases SyncRoot property returns the collection object itself.
Also read this answer about SyncRoot.
FYI: I've never seen SyncRoot usages in production code. So I suggest you to use instance of any collection as a synchronizing object instead of it's SyncRoot property (as long as the collection is private).

Is it considered bad design to do lengthy operations in a constructor?

I am implementing a class to compare directory trees (in C#). At first I implemented the actual comparison in the class's constructor. Like this:
DirectoryComparer c = new DirectoryComparer("C:\\Dir1", "C:\\Dir2");
But it doesn't feel "right" to do a possible lengthy operation in the constructor. An alternative way is to make the constructor private and add a static method like this:
DirectoryComparer c = DirectoryComparer.Compare("C:\\Dir1", "C:\\Dir2");
What do you think? Do you expect a constructor to be "quick"? Is the second example better or is it just complicating the usage of the class?
BTW:
I wont mark any answer as accepted because I don't think there is a correct answer, just preference and taste.
Edit:
Just to clarify my example a little. I'm not only insterested if the directories differs, I'm also interested in how they differ (which files). So a simple int return value wont be enough. The answer by cdragon76.myopenid.com actually is pretty close to what I want (+1 to you).
I would think a combination of the two is the "right" choice, as I would expect the Compare method to return the comparison result, not the comparer itself.
DirectoryComparer c = new DirectoryComparer();
int equality = c.Compare("C:\\Dir1", "C:\\Dir2");
...and as Dana mentions, there is an IComparer interface in .Net that reflects this pattern.
The IComparer.Compare method returns an int since the use of IComparer classes is primarily with sorting. The general pattern though fits the problem of the question in that:
Constructor initializes an instance with (optionally) "configuring" parameters
Compare method takes two "data" parameters, compares them and returns a "result"
Now, the result can be an int, a bool, a collection of diffs. Whatever fits the need.
I prefer the second one.
I expect the constructor to instanciate the class.
The method compare does what it is designed to do.
I think an interface might be what you're after. I would create a class to represent a directory, and have that implement the DirectoryComparer interface. That interface would include the compare method. If C# already has a Comparable interface, you could also just implement that.
In code, your call would be:
D1 = new Directory("C:\");
..
D1.compare(D2);
You should never do anything that might fail in a constructor. You don't want to ever create invalid objects. While you could implement a "zombie" state where the object doesn't do much, it's much better to perform any complex logic in seperate methods.
I agree with the general sentiment of not doing lengthy operations inside constructors.
Additionally, while on the subject of design, I'd consider changing your 2nd example so that the DirectoryComparer.Compare method returns something other than a DirectoryComparer object. (Perhaps a new class called DirectoryDifferences or DirectoryComparisonResult.) An object of type DirectoryComparer sounds like an object you would use to compare directories as opposed to an object that represents the differences between a pair of directories.
Then if you want to define different ways of comparing directories (such as ignoring timestamps, readonly attributes, empty directories, etc.) you could make those parameters you pass to the DirectoryComparer class constructor. Or, if you always want DirectoryComparer to have the exact same rules for comparing directories, you could simply make DirectoryComparer a static class.
For example:
DirectoryComparer comparer = new DirectoryComparer(
DirectoryComparerOptions.IgnoreDirectoryAttributes
);
DirectoryComparerResult result = comparer.Compare("C:\\Dir1", "C:\\Dir2");
Yes, typically a constructor is something quick, it is designed to prepare the object for use, not to actually do operations. I like your second option as it keeps it a one line operation.
You could also make it a bit easier by allowing the constructor to pass the two paths, then have a Compare() method that actually does the processing.
I like the second example because it explains what is exactly happening when you instantiate the object. Plus, I always use the constructor to initialize all of the global settings fro the class.
I think for a general purpose comparer you may on construction only want to specify the files you are comparing and then compare later- this way you can also implement extended logic:
Compare again- what if the directories changed?
Change the files you are comparing by updating the members.
Also, you may want to consider in your implementation receiving messages from your OS when files have been changed in the target directories- and optionally recomparing again.
The point is- you are imposing limits by assuming that this class will only be used to compare once for a single instance of those files.
Therefore, I prefer:
DirectoryComparer = new DirectoryComparer(&Dir1,&Dir2);
DirectoryComparer->Compare();
Or
DirectoryComparer = new DirectoryComparer();
DirectoryComparer->Compare(&Dir1,&Dir2);
I think it's not only okay for a constructor to take as much time as needed to construct a valid object, but the constructor is required to do so. Deferring object creation is very bad as you end up with potentially invalid objects. So, you will have to check an object everytime before you touch it (this is how it is done in the MFC, you have bool IsValid() methods everywhere).
I only see a slight difference in the two ways of creating the object. One can see the new operator as a static function of the class anyway. So, this all boils down to syntactic sugar.
What does the DirectoryComparer class do? What is it's responsibility? From my point of view (which is a C++ programmer's view) it looks like you'd be better off with just using a free function, but I don't think that you can have free functions in C#, can you? I guess you will collect the files which are different in the DirectoryComparer object. If so, you could better create something like an array of files or an equivalent class that's named accordingly.
If you are working with C#, you could use extension methods to create a method for comparing 2 directories that you would attach to the build in DirectoryClass, so it would look some thing like:
Directory dir1 = new Directory("C:\.....");
Directory dir2 = new Directory("D:\.....");
DirectoryCompare c = dir1.CompareTo(dir2);
This would be much clearer implementation.
More on extension methods here.
If an operation may take an unknown amount of time, it is an operation you might want to export into a different thread (so your main thread won't block and can do other things, like showing a spinning progress indicator for example). Other apps may not want to do this, they may want everything within a single thread (e.g. those that have no UI). Moving object creation to a separate thread is a bit awkward IMHO. I'd prefer to create the object (quickly) in my current thread and then just let a method of it run within another thread and once the method finished running, the other thread can die and I can grab the result of this method in my current thread by using another method of the object before dumping the object, since I'm happy as soon as I know the result (or keeping a copy if the result involves more details I may have to consume one at a time).
If the arguments are just going to be processed once then I don't think they belong as either constructor arguments or instance state.
If however the comparison service is going to support some kind of suspendable algorithm or you want to notify listeners when the equality state of two directories changes based on filesystem events or something like that. Then ther directories is part of the instance state.
In neither case is the constructor doing any work other than initializing an instance. In case two above the algorithm is either driven by a client, just like an Iterator for example, or it's driven by the event listening thread.
I generally try to do things like this:
Don't hold state in the instance if it can be passed as arguments to service methods.
Try to design the object with immutable state.
Defining attributes, like those used in equals and hashcode should allways be immutable.
Conceptualy a constructor is a function mapping an object representation to the object it represents.
By the definition above Integer.valueOf(1) is actually more of a constructor than new Integer(1) because Integer.valueOf(1) == Integer.valueOf(1).
,
In either case this concept also means that all the cosntructor arguments, and only the constructor argument, should define the equals behavior of an object.
I would definitely do the second.
Long actions in a constructor are fine if they are actually building the object so it is usable.
Now one thing that I see people do in constructors is call virtual methods. This is BAD since once someone uses you as a base class and overrides one of those functions you will call the base class's version not the derived class once you get into your constructor.
I don't think that talking about abstract terms like "lengthy" have anything to do with the decision if you put something in an constructor or not.
A constructor is something that should be used to initialize an object, a method should be used to "do something", i.e. have a function.

Categories

Resources