| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools |
Rating:
|
|
|
|
| |
|
Nate
Guest
Posts: n/a
|
On May 31, 1:26*pm, Nate <nhar...@ballytech.com> wrote:
> Excuse me if this has already been answered. *I've done many searches > on newsgroups, websites, and books, and have not found a method to do > what I want. > > Does there exist an idom or pattern in c# that will destroy, finalise, > or call some specified routine at a specified code point automatically > that will in-turn destroy or finalise all member objects of the class > automatically at the same code point? > > By "automatically", I mean that I do not want to have to write code > that calls each member object's destruction method, as that is not a > safe programming idiom (an engineer may add more member variables down > the line and forget to add calls to their finalisation method). > > As an example, in c++ with RAII, this is automated by the compiler > generated destructor mechanism. > > In particular, the usage I want is similar to a c++ smart-pointer in > that I do not want to have to make an explicit call to the > finalisation method of the containing object, but instead intend to > just "switch out" objects (so a new one replaces the old one - > initiating the destruction). > > This is used heavily in many classic designs in c++, particularly the > state pattern. *An event to a state machine may cause one state to > transition to another state, which eventually becomes code like: > > currentState_ = newState; *// destroy old state and start using new > > Ref objects only act like smart pointers in the reference counting, > not the deterministic destruction. *The "using" keyword appears to > only be a single-scope mechanism, so does not appear suitable for > event-based lifetimes. *The IDisposable methodology appears to require > explicit calls to dispose the object, to implement the IDisposable > interface, and recursively must dispose of all members explicitly. > > Some popular c# state libraries either do not appear to allow states > to contain objects or do not manage the lifetime of those objects > automatically. *I have not found anything that accomplishes this level > of automation yet, but I think I must be overlooking something simple. And just to be clear about my reasons here, I'm not just looking to destroy objects to clean up memory or because it is what I'm used to from c++. I wanted to make that point because I have seen a few discussions on this topic that mentioned one shouldn't think in those terms with a language like c# that has garbage collection, and that's not why I'm asking. In the state pattern, the whole point is that the state holds not only methods to handle events while the system is in that state but also actors in the system who exist while in that state. For instance, one wants: class AlertState : BaseState { NotificationBox alert_; // rest of member objects and methods }; where alert_ may be a notification message added to the model of the UI while in the alert state. This should be removed when the AlertState is replaced with another object. Good programming design should prevent the need to explicitly remove the box on exit (because of the N state x M object complexity of such code, or because of the duplicated lifetime specification being error prone and possibly divergent, etc.). Obviously, I don't need the objects dtor to be the method called, nor any known finalisation routines. The ability to call any method automatically would be sufficient here if I architect it early enough. |
|
||
|
||||
|
Nate
Guest
Posts: n/a
|
On May 31, 9:06 pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com> wrote:
> On 5/31/11 1:26 PM, Nate wrote: [...] > > By "automatically", I mean that I do not want to have to write code > > that calls each member object's destruction method, as that is not a > > safe programming idiom (an engineer may add more member variables down > > the line and forget to add calls to their finalisation method). > > Most member fields should not need any treatment whatsoever. The only > cleanup your code should worry about is when dealing with resources that > .NET itself cannot be aware of, either directly or indirectly (by > holding a reference to an object that implements IDisposable). I tried to make this clearer in my discussion of actors. Making states IDisposable does not automate the lifetime management of their members. Lifetime management is important not just for memory, but system participation in general. Deterministic finalisation should automate the finalisation of actors at the lifetime of the state. Not doing so is bad design, as it leaves open the possibility of an engineer forgetting to do the finalisation action explicitly. This is the same common design argument for all duplication of tasks - whether code duplication (where an engineer may updte one piece of code but not it's duplicate), serialisation (engineers may add a member but forget to serialise it), or managing type information as switch-on- enums (updating switch statements may miss a switch for a new enum) - in general you should reduce the specification an engineer must update to add functionality and prevent duplication of specification to prevent divergence. In the examples, the common design solutions are to use the same code (separate into a function), use introspective serialisation, and use encapsulation into objects. It's probably wrong to think of finalisation as needing to occur for "resources" because most people think only OS resources like files, windows, graphics surfaces, etc. Any actors that require finalisation as a part of lifetime management must be deterministically finalised. Some examples of actors that don't involve resources include: - regulatory logs of security activity (events of opening and closing doors on secure devices, for instance - the finalisation event being the logging of the closing door or leaving the open state) - notification data while in some state - addition and removal in the UI model (not to be confused with the UI graphic resources, but the actual data in the model when using proper MVC / MVP tripartite presentation designs) - communication with a host system on state notification (an "exiting state X" communication found in many protocols) The whole point of using a state pattern is that these things should become automated, to reduce the O(N events x M states) complexity of event handling to just those events that expect to be handled and to reduce the O(M^2 state-to-state) transition complexity to O(M state) construction/finalisation management. > > As an example, in c++ with RAII, this is automated by the compiler > > generated destructor mechanism. > > Only for stack-allocated objects. In C#, one pretty much never > allocates reference-type objects on the stack. > > > In particular, the usage I want is similar to a c++ smart-pointer in > > that I do not want to have to make an explicit call to the > > finalisation method of the containing object, but instead intend to > > just "switch out" objects (so a new one replaces the old one - > > initiating the destruction). > > You can't overload the assignment operator in C#, so that won't work > (note that in C++ the above is not the same as RAII; the "dispose on > assignment" works for a different reason, namely the implementation of > the overloaded assignment operator that goes with your smart-pointer class). The use of the term RAII in architectural circles is that there should never exist "zombie" objects, ie. objects which are not alive but not quite dead. Two phase initialisation, multiphase destruction, etc. all fall under the use of this term as espoused by Bjarne Stroustrup (who coined the term). The point is that objects should be usable for their lifetime (or that accessibility as objects should = their usability lifetime) to prevent errors where engineers accidentally use a zombie, and that in a language that allows exceptions, management of zombies can be combinatorial in complexity. So, my use here is fairly standard in those circles. I understand it may not be understood the same way in c# circles, so I hope this clarifies. > > This is used heavily in many classic designs in c++, particularly the > > state pattern. An event to a state machine may cause one state to > > transition to another state, which eventually becomes code like: > > > currentState_ = newState; // destroy old state and start using new > > Properly encapsulated, it is trivial to add the necessary call to > IDisposable.Dispose() when updating the current state reference (e.g. by > using a single property or other method to handle the update, and > calling Dispose() there). > > Again note that this has nothing to do with C++-style RAII, as the > objects are not allocated on the stack, nor does destruction happen as a > result of exiting a stack frame. The whole point of my question is how to avoid the explicit calls to all member actors in a state that would be placed inside the Dispose(bool) if I used IDisposable. The IDisposable pattern does not automate member finalisation - it must be done explicitly, which is error prone and bad design. I'm looking for other patterns that people may have in c# that solve this design issue (which is most certainly about RAII - RAII has nothing to do with stack-v-heap). > > Ref objects only act like smart pointers in the reference counting, > > not the deterministic destruction. > > There's no reference counting in .NET, except where you've implemented > it explicitly for some reason. I didn't say anything of the sort. I was saying that management of reference lifetimes ends when all references are no longer held, like smart pointers managed by reference counts. The fact that the GC walks reference graphs instead of using ref counting is immaterial to the point - they act like smart pointers in one regard, but don't provide the functionality (deterministic finalisation) that I need. So I'm looking for something else. > > The "using" keyword appears to > > only be a single-scope mechanism, so does not appear suitable for > > event-based lifetimes. > > Yet, it is .NET's equivalent to RAII, which is what you said you were > asking about (but of course as I've noted above, you've strayed from > that line of thought, so who really knows what you're asking). It's a shame that many c# users have such a limited view of RAII, because that totally misses Bjarne's original point. > > The IDisposable methodology appears to require > > explicit calls to dispose the object, to implement the IDisposable > > interface, and recursively must dispose of all members explicitly. > > > Some popular c# state libraries either do not appear to allow states > > to contain objects or do not manage the lifetime of those objects > > automatically. I have not found anything that accomplishes this level > > of automation yet, but I think I must be overlooking something simple. > > I believe you are overlooking the usefulness of the IDisposable pattern. > > Unfortunately, you have not actually posted any concrete code example of > a scenario showing what you'd like to do and why IDisposable or some > other approach doesn't help. -------------- Program.cs --------------------- namespace TestStateMachine { class Program { static void Main(string[] args) { // Make a state machine (default state 1) and fire event 1 StateMachine.Instance.Event1(); // fire event 2 StateMachine.Instance.Event2(); // fire event 3 StateMachine.Instance.Event3(); System.Threading.Thread.Sleep(10000); } } } --------- StateMachine.cs ------------- namespace TestStateMachine { public sealed class StateMachine { private static readonly StateMachine instance_ = new StateMachine(); private StateBase currentState_ = new State1(); private StateMachine() { } public static StateMachine Instance { get { return instance_; } } public void Event1() { currentState_.Event1(); } public void Event2() { currentState_.Event2(); } public void Event3() { currentState_.Event3(); } public void Transition(StateBase newState) { currentState_.Dispose(); currentState_ = newState; } }; } ------------ StateBase.cs ------------ using System; namespace TestStateMachine { public interface StateBase : IDisposable { void Event1(); void Event2(); void Event3(); } } ------------ State1.cs ----------------- using System; namespace TestStateMachine { public class State1 : StateBase { TestManageThisClass someObject = new TestManageThisClass(); public State1() { Console.WriteLine("Entered State1"); } ~State1() { Console.WriteLine("Leaving State1"); Dispose(false); } public void Event1() { if (disposed_) throw new ObjectDisposedException("State1"); StateMachine.Instance.Transition(new State2()); } public void Event2() { if (disposed_) throw new ObjectDisposedException("State1"); StateMachine.Instance.Transition(new State3()); } public void Event3() { if (disposed_) throw new ObjectDisposedException("State1"); StateMachine.Instance.Transition(new State4()); } private bool disposed_ = false; protected virtual void Dispose(bool disposing) { Console.WriteLine("State1 in Dispose"); if (!disposed_) { if (disposing) { // do nothing for managed to illustrate that members are not deterministic } Console.WriteLine("State1 now disposed"); disposed_ = true; } } public void Dispose() { Console.WriteLine("State1 in outer Dispose"); Dispose(true); GC.SuppressFinalize(this); } } } -------------------- TestManageThisClass.cs ----------------- using System; namespace TestStateMachine { public class TestManageThisClass { public TestManageThisClass() { Console.WriteLine("TestManageThisClass ctor"); } ~TestManageThisClass() { Console.WriteLine("TestManageThisClass dtor"); } } } // then similar for states 2 - 4 (left out for brevity) -------------------------------------------------- When I run my program, the output is: TestManageThisClass ctor Entered State1 Entered State2 State1 in outer Dispose State1 in Dispose State1 now disposed Entered State4 State2 in outer Dispose State2 in Dispose State2 now disposed Entered State3 State4 in outer Dispose State4 in Dispose State4 now disposed .... Notice that the contained object TestManageThisClass of State1 is not automatically and deterministically finalised. Instead, I would have to explicitly write in the Dispose(bool) method where I've left a comment an explicit call to finalisation, likely by deriving the TestManageThisClass type from IDisposable and callng Dispose(). As I've tried to point out, this is widely acknowledged to be a bad design and error prone, because it requires that an engineer duplicate the specification of member actors in the state in the member list and in the Dispose(bool) method, introducing the possibility of divergence. I mentioned the patterns I am aware of (using, IDisposable) for deterministic finalisation. None of these solve the problem for automating state based lifetime management. I was hoping someone might offer another means of solving this that is widely used, as I hope there are some c# developers out there that use good architectural practices and have solved this. Possibly using T4? Or reflection? There are 4 lifetimes that are commonly used in architecting programs: temporary - commonly anonymous objects that live for a statement or between sequence points scope - imperative objects used to perform procedural calculations within a function or more explicit scope state - actors that operate for the lifetime of a specific program state - ie. between asynchronous events application - objects that exist for the lifetime of the application It is clear that Microsoft eventually realised the necessity for deterministic finalisation of scope objects, because they created a number of statements in c# to manage these (lock, using, ...). Temporary objects have a number of useful idioms in other languages that take advantage of deterministic finalisation (like expression templates and expression proxies), but I don't need those for my project right now, so I'm not asking about those yet (they are also more advanced techniques, so I think I'd be less likely to get answers). Application objects already have proper lifetime management. It is the scope lifetimes that I would hope I could fnd some well known idioms to use, as they should have been developed with any project that uses good architectural practices. Is this any clearer? |
|
||
|
||||
|
Nate
Guest
Posts: n/a
|
It's clear that my question is being taken as an attack against c#. I understand that there must be sensitivities in play here, but I am not attacking anything. I am asking a serious question that I think is not being understood because of these sensitivities. I will try again to be clearer. On Jun 1, 11:33*pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com> wrote: > On 6/1/11 1:01 PM, Nate wrote: > > [...] > > The whole point of my question is how to avoid the explicit calls to > > all member actors in a state that would be placed inside the > > Dispose(bool) if I used IDisposable. *The IDisposable pattern does not > > automate member finalisation - it must be done explicitly, which is > > error prone and bad design. > > Baloney. *It's no more error-prone than C++ objects allocated on the > heap. *In fact, because C# offers a language-supported way to control > the effective lifetime of an IDisposable object in a code block-scoped > way, it's less error-prone than the equivalent approach in C++. > > Calling it "error prone" and "bad design" simply reveals your own > anti-C# bias. *Whether that's because you've got an axe to grind, or if > you've simply not had enough experience with C# to appreciate the > different idioms in the language that work just as well as those found > elsewhere, I don't know. *But the bias is clear. There is absolutely no bias. In fact, I am asking for an idiom to solve a design issue. Let me show the c++ side of what I would do: class State1 : public StateBase { SomeActorType actor1_; SomeActorType actor2_; public: // Event handlers interface, etc. }; When I enter State1, actor1_ and actor2_ would be created and their ctor called. When I leave State1, actor1_ and actor2_ would have their dtor called. All of this is automated by the language. In c#, if I were to use the IDisposable pattern, I require public class State1 : StateBase { private SomeActorType actor1_; private SomeActorType actor2_; protected virtual void Dispose(bool disposing) { // if ! disposed and disposing (just abbreviating) actor1_.Dispose(); actor2_.Dispose(); // rest of pattern } }; My point is that with the IDisposable pattern, you have to repeat the actors that you've already specified in the member list also in the Dispose(bool) function. That repitition is error-prone, because someone may add a member and forget to put it in the Dispose(bool). Anyone who has worked in a large project knows that specifying the intent more than once is a major source of errors. In fact, c# uses the GC to handle the common error in c of not matching all "malloc"s with "free". c# uses the "lock" statement to handle the common error in c of not matching "mutex_lock" calls with "mutex_unlock". And c# has the "using" statement to match many of the common scope-based duplication like file open/close, socket open/close, logging begin/ end, ... (although Microsoft has pointed out that since the Dispose method may throw and hide exceptions in the using block, it is often best not to use "using" but revert to the try/catch/finally triad). The trend in architecture, since the start of the generative programming days, is to reduce the specification of intent to best match the efficiencies found in the domain language. One of the simplest reductions is to remove duplicated specification. That is all I am trying to do. All I am asking is if there is a known idiom or pattern that people use to do this for _state_ lifetimes. You don't employ "using" for state lifetimes, because the objects don't live inside a scope. The objects live inside a state object because there are asynchronous events that determine the start and end of the lifetime. I am fairy positive that this can be done with reflection (I am almost finished with a solution that uses this and will be testing this afternoon), and as with all generative programming, I am certain it could also be done with code generation like T4. I know there are ways to solve this. I am simply asking if there is a "standard" or "well-known" pattern that has been used regularly. It is always best to use common solutions, because they are regularly less complex because they have had more eyes on them and more time to be refined. I expected this was something that any good architects moving to c# would have faced many times in the past and come up with something. I didn't expect to touch on silly sensitivities and misunderstandings of the intent of RAII and start some newsgroup war, but I guess those kinds of things are hard to avoid on the newsgroups... |
|
||
|
||||
|
Nate
Guest
Posts: n/a
|
On Jun 2, 9:37*am, Nate <nhar...@ballytech.com> wrote:
> It's clear that my question is being taken as an attack against c#. *I > understand that there must be sensitivities in play here, but I am not > attacking anything. *I am asking a serious question that I think is > not being understood because of these sensitivities. *I will try again > to be clearer. > > On Jun 1, 11:33*pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com> wrote: > > On 6/1/11 1:01 PM, Nate wrote: > > > [...] > > > The whole point of my question is how to avoid the explicit calls to > > > all member actors in a state that would be placed inside the > > > Dispose(bool) if I used IDisposable. *The IDisposable pattern does not > > > automate member finalisation - it must be done explicitly, which is > > > error prone and bad design. > > > Baloney. *It's no more error-prone than C++ objects allocated on the > > heap. *In fact, because C# offers a language-supported way to control > > the effective lifetime of an IDisposable object in a code block-scoped > > way, it's less error-prone than the equivalent approach in C++. > > > Calling it "error prone" and "bad design" simply reveals your own > > anti-C# bias. *Whether that's because you've got an axe to grind, or if > > you've simply not had enough experience with C# to appreciate the > > different idioms in the language that work just as well as those found > > elsewhere, I don't know. *But the bias is clear. > > There is absolutely no bias. *In fact, I am asking for an idiom to > solve a design issue. *Let me show the c++ side of what I would do: > > class State1 : public StateBase > { > * SomeActorType actor1_; > * SomeActorType actor2_; > > public: > * // Event handlers interface, etc. > > }; > > When I enter State1, actor1_ and actor2_ would be created and their > ctor called. *When I leave State1, actor1_ and actor2_ would have > their dtor called. *All of this is automated by the language. > > In c#, if I were to use the IDisposable pattern, I require > > public class State1 : StateBase > { > * private SomeActorType actor1_; > * private SomeActorType actor2_; > > * protected virtual void Dispose(bool disposing) > * { > * * // if ! disposed and disposing (just abbreviating) > * * actor1_.Dispose(); > * * actor2_.Dispose(); > > * * // rest of pattern > * } > > }; > > My point is that with the IDisposable pattern, you have to repeat the > actors that you've already specified in the member list also in the > Dispose(bool) function. *That repitition is error-prone, because > someone may add a member and forget to put it in the Dispose(bool). > > Anyone who has worked in a large project knows that specifying the > intent more than once is a major source of errors. *In fact, c# uses > the GC to handle the common error in c of not matching all "malloc"s > with "free". *c# uses the "lock" statement to handle the common error > in c of not matching "mutex_lock" calls with "mutex_unlock". *And c# > has the "using" statement to match many of the common scope-based > duplication like file open/close, socket open/close, logging begin/ > end, ... (although Microsoft has pointed out that since the Dispose > method may throw and hide exceptions in the using block, it is often > best not to use "using" but revert to the try/catch/finally triad). > > The trend in architecture, since the start of the generative > programming days, is to reduce the specification of intent to best > match the efficiencies found in the domain language. *One of the > simplest reductions is to remove duplicated specification. *That is > all I am trying to do. *All I am asking is if there is a known idiom > or pattern that people use to do this for _state_ lifetimes. *You > don't employ "using" for state lifetimes, because the objects don't > live inside a scope. *The objects live inside a state object because > there are asynchronous events that determine the start and end of the > lifetime. > > I am fairy positive that this can be done with reflection (I am almost > finished with a solution that uses this and will be testing this > afternoon), and as with all generative programming, I am certain it > could also be done with code generation like T4. *I know there are > ways to solve this. *I am simply asking if there is a "standard" or > "well-known" pattern that has been used regularly. *It is always best > to use common solutions, because they are regularly less complex > because they have had more eyes on them and more time to be refined. > > I expected this was something that any good architects moving to c# > would have faced many times in the past and come up with something. *I > didn't expect to touch on silly sensitivities and misunderstandings of > the intent of RAII and start some newsgroup war, but I guess those > kinds of things are hard to avoid on the newsgroups... I finished up a preliminary implementation of a reflection solution to demonstrate that that method worked. It's basic procedure for an external IDisposable looks like: // use reflection to get the objects in holder FieldInfo[] mInfos = holder.GetType().GetFields(); // loop through members foreach (FieldInfo mInfo in mInfos) { // first print what info I can get Console.WriteLine("Found member: " + mInfo.Name + " of type " + mInfo.FieldType); .// now try to call Dispose on each member if (typeof(IDisposable).IsAssignableFrom(mInfo.FieldType)) { Console.WriteLine("This is derived from IDisposable!"); // get the value object object value = mInfo.GetValue(holder); Console.WriteLine("Got value object of type " + value.GetType().Name); // so invoke mInfo.FieldType.GetMethod("Dispose", new Type[0]).Invoke(value, new object[0]); } } Now, instead of just using this at a single level working on an external object (the holder type above), I've taken a recursive approach and created a type RecursiveDisposable derived from IDisposable which has a method RecursivelyDispose that implements the same technique on the self type. This allows deterministic finalisation of all RecursiveDisposable types. Then, my state machine calls RecursivelyDispose on the state that is exiting and all actors will be removed from the system properly and without duplication of specification during the state transition. My biggest concern is the time involved in invoking methods by string. So I will pursue a T4 solution next to weigh options here. Are there any other approaches foreseeable? |
|
||
|
||||
|
Nate
Guest
Posts: n/a
|
On Jun 2, 5:37*pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com> wrote:
> On 6/2/11 9:37 AM, Nate wrote: > > > There is absolutely no bias. > > Of course there is. *You've stated several times that C# is deficient in > this area, when in fact it's not. *It simply has a different idiom than > you're used to. > > Your false criticisms of the language can occur only either because > you've started with a false premise that you have some compulsion to > prove, or simply out of ignorance. *Either way, it's a bias. Dude, I really have no idea what your issues are, why you like to attack people online instead of answer their questions, who hurt you, whatever. I don't really want to know. This will be the last time I respond to you because I have actual work to do and family to be with. But it is strange how you've convinced yourself that I believed there was no answer to my question when 1) I mentioned reflection and T4 early in the discussion, and 2) I ended up answering my own question because you were too busy masturbating about how great the idiom that didn't answer my question really was. If I had wanted to start an argument that simply bashes a language, I would have gone over to the c ++ groups and pointed out how even the newest updates to the language fail to allow serialisation without duplication (but c# reflection solves it fine). Or I would have come over here and pointed out that without RAII, c# makes you have to write finalisation code everywhere a class requiring disposal is used instead of how in c++, the exception mechanism calls dtors and automates cleanup, making c++ a much safer language in the face of exceptions. Or I'd go to the OCaml groups and point out that since they allow imperative state, they aren't a true functional language. Every language has something true about it that hurts people and mentioning it makes it users sore. But this _obviously_ wasn't one, since I mentioned possible solutions early on and eventually solved it myself. So how you've convinced yourself I was here to pick a fight, when I was only mentioning truthful statements about how the standard idioms failed to resolve my particular issue, is completely unknown. > > In fact, I am asking for an idiom to > > solve a design issue. *Let me show the c++ side of what I would do: > > > class State1 : public StateBase > > { > > * *SomeActorType actor1_; > > * *SomeActorType actor2_; > > > public: > > * *// Event handlers interface, etc. > > }; > > > When I enter State1, actor1_ and actor2_ would be created and their > > ctor called. *When I leave State1, actor1_ and actor2_ would have > > their dtor called. *All of this is automated by the language. > > Only because you have embedded the types within the container type. *If > you were actually using true reference types throughout, you'd have the > same issue as in C#. It is a really strange complaint that I am using the state pattern as one is supposed to. Sure, if I do things wrong, I'll get bad results. Why does this line of thought even come to your mind? > > In c#, if I were to use the IDisposable pattern, I require > > > public class State1 : StateBase > > { > > * *private SomeActorType actor1_; > > * *private SomeActorType actor2_; > > > * *protected virtual void Dispose(bool disposing) > > * *{ > > * * *// if ! disposed and disposing (just abbreviating) > > * * *actor1_.Dispose(); > > * * *actor2_.Dispose(); > > > * * *// rest of pattern > > * *} > > }; > > > My point is that with the IDisposable pattern, you have to repeat the > > actors that you've already specified in the member list also in the > > Dispose(bool) function. *That repitition is error-prone, because > > someone may add a member and forget to put it in the Dispose(bool). > > If you follow the ComponentModel pattern found in .NET, then disposable > objects are added to a list of components. *They still need to be added, > but the Dispose() method requires no changes if disposable objects are > added. Sure, I can change compiletime contracts to runtime contracts and lose even greater compiler error detection. That's the wrong direction to go based on nearly every book on safe architecture I've ever read, where the big goal in domain language mapping is to enforce more compiler contracts through compiletime type information. But sure, if I like to do things poorly, I totally could. > More to the point, you have lots of opportunities besides this to > "forget" to do something important. *Fact is, disposable objects are > much less common than plain vanilla ones that don't require special > handling, and for skilled programmers, it's not a problem at all to > remember to dispose one's disposable objects. > > Adding a new field to a class involves a laundry list of things that > have to be done in order to incorporate that object into the class. > Unless you're a particularly careless person, you are much more likely > to screw up the main implementation details than to forget to add the > object to the IDisposable implementation (especially since most of the > time, it's just going to be automatic as soon as you add the field to > also add the dispose call). Of course. Which is why assembly is so popular. I mean, we don't need procedural names since any skilled programmer can choose the right relocatable address to jump to as needed, or the proper data layout that they intend to manipulate. Seriously, you are arguing that my concern is unwarranted when Microsoft took the effort and money to add a GC and "using" and "lock" statements to the language and suggest that using them is preferred practice, when all design in c++ has held that as best practice, when there is a mathematical theorem in computational grammar correctness theory that proves such a reduction reduces the code points where contradicting intent may occur... You can code in unsafe mode c# all you want, remember all the silly things that c# could be taking care of for you, and prove to yourself what a manly programmer you are. I've coded in Fortran and c earlier in my career, so I know I can do it. I don't need to prove to myself anything on my company's time. Instead, I want to provide a design to my engineers that makes it so they don't have unnecessary possibilities of error. They can screw up the intent through logical errors and there is nothing I can do to prevent that - that's always the case. I see no need in adding places where they can mess up by failing to duplicate data. > > [...] (although Microsoft has pointed out that since the Dispose > > method may throw and hide exceptions in the using block, it is often > > best not to use "using" but revert to the try/catch/finally triad). > > More misunderstanding on your part. *I have no idea what you read that > gave you that idea, but whatever it was, you didn't understand it correctly. > > A Dispose() method that catches exceptions will do so whether you use a > "using" statement or a "try/finally". *The only reason to use > "try/catch/finally" instead of "using" is if you have other stuff that > needs to go into the "finally" anyway. I love how you, who misunderstood my question in a number of hilarious (and probably embarrassing) posts want desperately to claim that I am the one misunderstanding things. If you look at http://msdn.microsoft.com/en-us/library/aa355056.aspx you will see how they discuss the fact that when a Dispose may throw, like in their client sample for WCF (or many of the other explicit resource IDisposables in .NET and many user-defined classes requiring finalisation that adds something to an internal collection like a log, among other examples), then the using construct may throw upon closing. This means that exceptions thrown inside the using statement block may be hidden by the outer finally-originated throw. When the finaliser may throw, there is the need for Abort-like constructs to ensure resources are still proper cleaned and no leaks occur. This is pretty well known by most who have any WCF or related experience. But I can understand that if you are not informed about such things, it might sound like it is other people who are misinformed. It's called the Dunning-Kruger effect, and it's quite common. > > [...] * I > > didn't expect to touch on silly sensitivities and misunderstandings of > > the intent of RAII and start some newsgroup war, but I guess those > > kinds of things are hard to avoid on the newsgroups... > > If you don't want to touch on "silly sensititivites" (ad hominem much?), > then you shouldn't go around make ignorant claims about deficiencies of > the language you are asking about. Since I assumed there was a solution, eventually solved it myself while you were still stumbling with the question, and have had, in the process, to bear a series of posts from you labeling me ignorant (where I never once until this post reciprocated the accusation - despite you being the one who showed on numerous responses that you were the one lacking common knowledge of terms commonly used in the architectural community), I think "silly sensitivities" is a reasonable description of your behavior. Project much? Oh, and for your own education, down the road and all, if you ever get into another these discussions, you might want to learn how to google search before claiming terms used are made up or not common in front of all other newsgroup visitors that might read your silliness. For instance, http://www.google.com/search?client=...UTF-8&oe=UTF-8 Peace and love, Pete. I hope you get some help. As I mentioned above, this is my last response to you. |
|
||
|
||||
|
ozbear
Guest
Posts: n/a
|
On Thu, 2 Jun 2011 21:29:25 -0700 (PDT), Nate <(E-Mail Removed)>
wrote: >On Jun 2, 5:37=A0pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com> wrote: >> On 6/2/11 9:37 AM, Nate wrote: >> >> > There is absolutely no bias. >> >> Of course there is. =A0You've stated several times that C# is deficient i= >n >> this area, when in fact it's not. =A0It simply has a different idiom than >> you're used to. >> >> Your false criticisms of the language can occur only either because >> you've started with a false premise that you have some compulsion to >> prove, or simply out of ignorance. =A0Either way, it's a bias. > >Dude, I really have no idea what your issues are, why you like to >attack people online instead of answer their questions, who hurt you, >whatever. I don't really want to know. This will be the last time I >respond to you because I have actual work to do and family to be with. <snip> Nate, your reaction to Pete is understandable. Although occaionally knowledgeable on some aspects of C# and .net, he uses his knowledge as a club to belittle and berate people who ask questions. You have come to the same conclusion as many of us that it's just not worth getting an answer from such an individual. Oz -- A: Because it fouls the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
||
|
||||
|
James A. Fortune
Guest
Posts: n/a
|
On Jun 7, 2:38*am, ozb...@bigpond.com (ozbear) wrote:
> Nate, your reaction to Pete is understandable. *Although occaionally > knowledgeable on some aspects of C# and .net, he uses his knowledge as > a club to belittle and berate people who ask questions. *You have come > to the same conclusion as many of us that it's just not worth getting > an answer from such an individual. As with all posters, our words eventually stand or fail on their own merits. I will play your game to this extent: Peter Duniho has not come across to me the way that you are suggesting in providing any answers to me. I am determined enough that I will eventually find the answers on my own even without Peter Duniho being available, so he is not an exclusive repository of knowledge; but his insights save me considerable time in coming to certain conclusions and philosophies about C#. I would eventually like to reach or surpass his expertise in C#. If so, I also hope to match or exceed his level of professionalism when answering questions about C#, and to keep in mind the amount of help I received to get there. Those of us who post answers based on our experiences hope that those experiences will make everyone better. I try to be as clear as I can when asking or answering questions. I try to share what I can with humility and goodwill, not minding at all if what I share helps someone else surpass me. Such helpful people should be forgiven any small conceits that initially help spur us on. Besides, he's had a wit like you to deal with. That accounts for half of his irritability :-). You are actually very clever, but you're also very annoying. As far as sympathy for being made to feel inferior by Peter, you can recruit bleeding hearts elsewhere. IMO, you couldn't be made to feel inferior if your life depended upon it, so don't act so wounded. You've done that many times. Even if Peter actually made someone feel bad, it wouldn't be as bad as your sorry act. You've actually helped my understanding of C# by asking the questions you have - but, O, the price! James A. Fortune (E-Mail Removed) |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| ASP.NET 2.0 Session State Scope | =?Utf-8?B?Tm9yZW1hYw==?= | Microsoft ASP .NET | 3 | 13th Aug 2007 02:29 AM |
| ANN: Machines of Destruction | illusionsoftware.be | Freeware | 6 | 17th Oct 2005 10:51 PM |
| deterministic destruction support for managed types in VC++ 2005beta 1 | Slawomir Lisznianski | Microsoft VC .NET | 2 | 26th Jul 2004 01:52 AM |
| ADSI returning groups in Global scope and Domain local scope instead of Universal scope | Maziar Aflatoun | Microsoft C# .NET | 1 | 21st Apr 2004 04:08 PM |
| How to count the number of machines per DHCP scope | Ralf | Microsoft Windows 2000 Networking | 1 | 11th Sep 2003 03:01 AM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |





