|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Access member variable directly or through property within the class it is defined?Suppose I have the following class: ---snip--- Public Class MyClass Private _MyVariable As Integer Public Property MyVariable() As Integer Get Return Me._MyVariable End Get Set(ByVal value As Integer) '(some value checking going on here) Me._MyVariable = value End Set End Property Private Sub MyMethod1 _MyVariable = 0 End Sub Private Sub MyMethod2 MyVariable = 0 End Sub End Class ---snip--- Is there a recommended best practice (class library design guidelines?) for accessing _MyVariable? MyMethod1 takes the direct route, thereby bypassing any value checking and side effects in the property setter. MyMethod2 goes through the property setter, which has the benefit of value checking/side effects, but might be overkill considering the performance hit incurred by the extra function call, especially if the values assigned are known to be valid. Still, if the priority is *maintainability*, wouldn't it be best only to use the direct access in the constructor only and the property setter in all other cases? To avoid multiple side effects as a result of setting multiple properties at once (e.g. if the class is a graphical control), would the best practice be to disable all updates, set multiple properties, then enable updates again, in order to use property setters all the time internally? What do you do? /JB IMHO, I think it's perfectly fine for a Class to "internally" set its
private variables without going through their Accessors. The class (you as the developer) should know when this makes sense and when it doesn't. For instance, when you want PropertyChanged events to be raised with databound-aware classes (yes, even regular ol' classes support this) then you'll probably want to change properties via their Accessors. It should be noted that there is practically 0% performance impact by going through the Accessors.... however, for the situations where Property Accessors actually do WORK, then for the sake of consistency and maintainability (and maybe performance)... sometimes implementing a WindowsForms-like 'SuspendLayout' - Modify Lots of Properties - 'ResumeLayout' is nice and elegant even INSIDE the class. This is situation-specific and definately not a "rule." In short... it's up to you. P.S. Now, whether you should be using PascalCase and underscores for private variables is a totally different matter. That IS a religious question. ;-) P.P.S. When accessing *Properties Accessors* internally it helps maintainability to do so using "Me." This is a fairly common coding standard (unfortunately not so much in the VB world). The rule doesn't really apply to the variables themselves or to Methods... just Properties. If you use this practice for awhile, you'll see why it makes sense. Show quoteHide quote "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message news:vo7ov11t193suj30s0s7rhef9tuiohmurb@4ax.com... > > (Slightly religious question): > > Suppose I have the following class: > > ---snip--- > Public Class MyClass > Private _MyVariable As Integer > > Public Property MyVariable() As Integer > Get > Return Me._MyVariable > End Get > Set(ByVal value As Integer) > '(some value checking going on here) > Me._MyVariable = value > End Set > End Property > > Private Sub MyMethod1 > _MyVariable = 0 > End Sub > > Private Sub MyMethod2 > MyVariable = 0 > End Sub > > End Class > ---snip--- > > Is there a recommended best practice (class library design > guidelines?) for accessing _MyVariable? > > MyMethod1 takes the direct route, thereby bypassing any > value checking and side effects in the property setter. > > MyMethod2 goes through the property setter, which has > the benefit of value checking/side effects, but might be > overkill considering the performance hit incurred by the > extra function call, especially if the values assigned are > known to be valid. > > Still, if the priority is *maintainability*, wouldn't it be best only > to use the direct access in the constructor only and the > property setter in all other cases? To avoid multiple side > effects as a result of setting multiple properties at once > (e.g. if the class is a graphical control), would the best > practice be to disable all updates, set multiple properties, > then enable updates again, in order to use property setters > all the time internally? > > What do you do? > > /JB > > > Joergen,
Maybe can the only problem be that you come in trouble in version 2005 because the start with an underscore for a variable is not always CLS compliant. See a long current thread in this newsgroup from someone who was in trouble with that. I have only touched it slightly. In fact are your methods 1 and 2 without sense. And therefore I would absolute not implement them at all. Cor "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> schrieb: Well, but this does not apply to private variables.> Maybe can the only problem be that you come in trouble in version 2005 > because the start with an underscore for a variable is not always CLS > compliant. > > See a long current thread in this newsgroup from someone who was in > trouble with that. I have only touched it slightly. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> >> Maybe can the only problem be that you come in trouble in version 2005 So I wrote it correct?>> because the start with an underscore for a variable is not always CLS >> compliant. >> >> See a long current thread in this newsgroup from someone who was in >> trouble with that. I have only touched it slightly. > > Well, but this does not apply to private variables. > > -- :-) CorUnderscores or no underscores and whether the methods
are useful for anything is besides the point. I am aware that I need to re-read some guidelines for coding style. Some other time. The question was about best practices for accessing member variables. The sample was written as concisely as possible to illustrate the differences. /JB On Wed, 22 Feb 2006 11:14:51 +0100, "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote: Show quoteHide quote >Joergen, > >Maybe can the only problem be that you come in trouble in version 2005 >because the start with an underscore for a variable is not always CLS >compliant. > >See a long current thread in this newsgroup from someone who was in trouble >with that. I have only touched it slightly. > >In fact are your methods 1 and 2 without sense. And therefore I would >absolute not implement them at all. > >Cor >
Show quote
Hide quote
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb: I do not know if there is a recommendation, but I recomment to call the > ---snip--- > Public Class MyClass > Private _MyVariable As Integer > > Public Property MyVariable() As Integer > Get > Return Me._MyVariable > End Get > Set(ByVal value As Integer) > '(some value checking going on here) > Me._MyVariable = value > End Set > End Property > > Private Sub MyMethod1 > _MyVariable = 0 > End Sub > > Private Sub MyMethod2 > MyVariable = 0 > End Sub > > End Class > ---snip--- > > Is there a recommended best practice (class library design > guidelines?) for accessing _MyVariable? accessor instead of accessing the private variable even in the class. The advantage of doing that is that validation code gets executed and that it's guaranteed that the private variable never holds an invalid value. This prevents errors from occuring in algorithms and methods relying on the property's value. By accessing the property duplicated range-checking code can be removed and put into the property's 'Set' part only. The runtime overhead for accessing the property instead of the variable should be minimal given the JITter could inline the property access in some cases. > Still, if the priority is *maintainability*, wouldn't it be best only I /always/ set the property value through the property.> to use the direct access in the constructor only and the > property setter in all other cases? -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> >> Still, if the priority is *maintainability*, wouldn't it be best only The constructor is *the* one place where I normally would want>> to use the direct access in the constructor only and the >> property setter in all other cases? > >I /always/ set the property value through the property. to initialize all the members directly, without any checks or side effects, but come to think of it ... good point you made there. /JB I don't think there's much controversy in any development community
concerning this. The only general rule is that Accessors (C++ terminology) must be used by other classes. Inside the class, you're free to do as you wish... as long as its consistent. I agree with the others here that it's "good" if you use the Accessors internally..... ..... though I myself don't care much for it. I use it only when it makes sense to do so. Consistency is the Golden Rule. If you decide to *mainly* access the variables directly, then only use the Accessors when you want to trigger whatever work they do (validation, etc). If you decide to *mainly* use Accessors, then only use the member variables for a darn good reason. That way it becomes instantly clear to anyone maintaining your code what your intentions were in a particular line of code.... "oh I see, he's accessing the variable on purpose to sidestep the validation in this special case." P.S. Yes, I know this is slightly OT... but, one thing I would stress again is using Me (for Properties). This is a pretty strict standard in the development world (even though not many of us VB folks practice it... to our detriment). Show quoteHide quote "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message news:2gfov198dfdnl4o7ll6ht4mhctc7n25sop@4ax.com... > >>> Still, if the priority is *maintainability*, wouldn't it be best only >>> to use the direct access in the constructor only and the >>> property setter in all other cases? >> >>I /always/ set the property value through the property. > > The constructor is *the* one place where I normally would want > to initialize all the members directly, without any checks or > side effects, but come to think of it ... good point you made there. > > /JB > > > >.... though I myself don't care much for it. I use it only when it makes Yes, Consistency is the key word, and since I am just starting a major>sense to do so. Consistency is the Golden Rule. If you decide to *mainly* new project, I was looking for some "official" guidelines, e.g. FxCop, Design Guidelines for Class Library Developers, SSW rules (http://ssw.com.au/SSW/Standards/Default.aspx), and yes, general recommendations from this group (or links to more guidelines). >P.S. Yes, I know this is slightly OT... but, one thing I would stress again The examples in Microsoft's own guidelines document use>is using Me (for Properties). This is a pretty strict standard in the >development world (even though not many of us VB folks practice it... to >our detriment). m_myVariable i.e. camel Casing for fields, and accessed without the Me keyword (I am talking about the VB examples), but the framework itself just uses camel Casing, without the m_ prefix. So yes I agree, choose and stick with the choice. I suppose prefixing the private fields with "m_" is the best approach: If this is used consistently, there is never any doubt whether the field is accessed directly or through the accessor. I like the prefix approach (whether it is "_" or "m_") as it allows me to use the "same" name for the field as well as the accessor. Visually, using "Me." is a good argument if just using the "_" prefix, but might be overkill if using the "m_" prefix(?) Hm ... I cannot use the same name and let the scope rules determine what is what, i.e. look at CheckBox.CheckState in the framework: Private checkState As CheckState Public Property CheckState As CheckState Get Return Me.checkState End Get ... End Property Such code is for C#-programmers with their case-sensitivity. .... Actually ... re-reading the Microsoft guidelines, they talk a lot about how the classes should look externally, but no naming conventions (that I can find) for private fields. Some examples use the "m_" prefix, others postfix their fields with "Value" (e.g. xValue for a property named X). Only consistent thing is the use of camel Casing. So I guess I am down to "Me._myVariable" or "m_myVariable". /JB I meant Me is used with Properties (Me.PropertyX = someValue). For member
variables you don't need to because usually their camelCase and/or scope_notation ("m_" or "_" which is also not required... though camelCase is) is enough. Show quoteHide quote "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message news:pssov1hlci2aqr2790jgta2jhc3dr2rj9a@4ax.com... > >.... though I myself don't care much for it. I use it only when it makes >>sense to do so. Consistency is the Golden Rule. If you decide to *mainly* > > Yes, Consistency is the key word, and since I am just starting a major > new project, I was looking for some "official" guidelines, e.g. FxCop, > Design Guidelines for Class Library Developers, SSW rules > (http://ssw.com.au/SSW/Standards/Default.aspx), > and yes, general recommendations from this group (or links to more > guidelines). > >>P.S. Yes, I know this is slightly OT... but, one thing I would stress >>again >>is using Me (for Properties). This is a pretty strict standard in the >>development world (even though not many of us VB folks practice it... to >>our detriment). > > The examples in Microsoft's own guidelines document use > > m_myVariable > > i.e. camel Casing for fields, and accessed without the Me > keyword (I am talking about the VB examples), but the framework > itself just uses camel Casing, without the m_ prefix. > > So yes I agree, choose and stick with the choice. > > I suppose prefixing the private fields with "m_" is the best approach: > If this is used consistently, there is never any doubt whether the > field is accessed directly or through the accessor. I like the prefix > approach (whether it is "_" or "m_") as it allows me to use the "same" > name for the field as well as the accessor. Visually, using "Me." is > a good argument if just using the "_" prefix, but might be overkill > if using the "m_" prefix(?) Hm ... I cannot use the same > name and let the scope rules determine what is what, i.e. look > at CheckBox.CheckState in the framework: > > Private checkState As CheckState > Public Property CheckState As CheckState > Get > Return Me.checkState > End Get > ... > End Property > > Such code is for C#-programmers with their case-sensitivity. > > ... > > Actually ... re-reading the Microsoft guidelines, they talk a lot > about how the classes should look externally, but no naming > conventions (that I can find) for private fields. Some examples > use the "m_" prefix, others postfix their fields with "Value" > (e.g. xValue for a property named X). > > Only consistent thing is the use of camel Casing. > > So I guess I am down to "Me._myVariable" or "m_myVariable". > > /JB > > > On Wed, 22 Feb 2006 12:55:06 -0500, "CMM" <cmm@nospam.com> wrote: Unless the field is prefixed with "m_" or "_", I would not necessarily>I meant Me is used with Properties (Me.PropertyX = someValue). For member >variables you don't need to because usually their camelCase and/or >scope_notation ("m_" or "_" which is also not required... though camelCase >is) is enough. interpret a camelCased variable used in a method as a member variable. It could just as well be a parameter, since the Microsoft guidelines for parameters specify camelCasing. So if "Me." was used to identify member variables or their accessors, why not go all the way and use it to indicate that any method or function call prefixed with "Me." belonged to the class? Where should the line be drawn? Methinks Me is overused. It's late here in GMT+1. Me is tired now :) /JB "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message Common convention says it doesn't matter. Just like it doesn't matter if a news:alepv1dnk2l4a72ogepah6vol1a29rs2jp@4ax.com... > On Wed, 22 Feb 2006 12:55:06 -0500, "CMM" <cmm@nospam.com> wrote: > >>I meant Me is used with Properties (Me.PropertyX = someValue). For member >>variables you don't need to because usually their camelCase and/or >>scope_notation ("m_" or "_" which is also not required... though camelCase >>is) is enough. > > Unless the field is prefixed with "m_" or "_", I would not necessarily > interpret a camelCased variable used in a method as a member variable. variable is a parameter or a local. Likewise, you also don't need to scope global variables with "g_" or constants with upper_case. Note: I don't necessarily agree with this on a personal level..... just stating what is a common tide nowadays. I don't disagree with it either.... if you use it for a while you might find it's quite liberating and doesn't take away from code readability at all. > MS guideliness call for camelCasing for all variables. PascalCasing for > It could just as well be a parameter, since the Microsoft guidelines > for parameters specify camelCasing. public members. > The line is drawn at Properties. Simple as that. Why? Well, because you > So if "Me." was used to identify member variables or their accessors, > why not go all the way and use it to indicate that any method or > function call prefixed with "Me." belonged to the class? Where should > the line be drawn? don't use Me to indicate scope (again, it doesn't matter) you're using it to indicate that you're accessing a temporal attribute of the class. > Me.HearsYa = True> Methinks Me is overused. It's late here in GMT+1. Me is tired now :) ;-) "CMM" <cmm@nospam.com> schrieb: ACK.>I don't think there's much controversy in any development community >concerning this. The only general rule is that Accessors (C++ terminology) >must be used by other classes. Inside the class, you're free to do as you >wish... as long as its consistent. I agree with the others here that it's >"good" if you use the Accessors internally..... > .... though I myself don't care much for it. I use it only when it makes I don't think consistency is the Golden Rule. Imagine a class having a > sense to do so. Consistency is the Golden Rule. property 'Age As Integer' and 'Name As String'. While validating a value assigned to 'Age' definitely makes sense and can help to avoid bugs in the code, it will never be necessary to perform validaton on a person's name, which can be an arbitrary string. > If you decide to *mainly* access the variables directly, then only use the Could you think of a real-world sample where sidestepping the validation > Accessors when you want to trigger whatever work they do (validation, > etc). If you decide to *mainly* use Accessors, then only use the member > variables for a darn good reason. That way it becomes instantly clear to > anyone maintaining your code what your intentions were in a particular > line of code.... "oh I see, he's accessing the variable on purpose to > sidestep the validation in this special case." would make sense? -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> Sure:
1) The property is ReadOnly... like is often the case when you expose collections or another complex object. You usually do this when you want to maintain a particular instance of an object for whatever reason, allow external classes to manipulate but not "switch" the object, but, inside the class you should be able to do whatever you want with the object. 2) The property has an "interpreted" fallback value given to the outside world (If value = 0 Return -1)... but internally it is not useful to the class. 3) Setting the property would cause an event to trigger or other code to execute that is not useful to the class. Granted, there are more elegant ways to do this (like the Form SuspendLayout, ResumeLayout example I gave in another post). I guess the assumption is that the class should know not to give a private member an "invalid" value that would otherwise not be possible using the Accessor.... and if it does do so, it's doing it *knowingly.* Furthermore, it depends on what the class *does* IMHO, a "Property Accesor Only" class might work well for regular ol' entity classes that represent "data" (like a Person class) but not so much for a Custom Control, Form, or other "action" oriented class that does more than just house information. Show quoteHide quote "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message news:%23kt4N38NGHA.208@tk2msftngp13.phx.gbl... > "CMM" <cmm@nospam.com> schrieb: >>I don't think there's much controversy in any development community >>concerning this. The only general rule is that Accessors (C++ terminology) >>must be used by other classes. Inside the class, you're free to do as you >>wish... as long as its consistent. I agree with the others here that it's >>"good" if you use the Accessors internally..... > > ACK. > >> .... though I myself don't care much for it. I use it only when it makes >> sense to do so. Consistency is the Golden Rule. > > I don't think consistency is the Golden Rule. Imagine a class having a > property 'Age As Integer' and 'Name As String'. While validating a value > assigned to 'Age' definitely makes sense and can help to avoid bugs in the > code, it will never be necessary to perform validaton on a person's name, > which can be an arbitrary string. > >> If you decide to *mainly* access the variables directly, then only use >> the Accessors when you want to trigger whatever work they do (validation, >> etc). If you decide to *mainly* use Accessors, then only use the member >> variables for a darn good reason. That way it becomes instantly clear to >> anyone maintaining your code what your intentions were in a particular >> line of code.... "oh I see, he's accessing the variable on purpose to >> sidestep the validation in this special case." > > Could you think of a real-world sample where sidestepping the validation > would make sense? > > -- > M S Herfried K. Wagner > M V P <URL:http://dotnet.mvps.org/> > V B <URL:http://classicvb.org/petition/> "CMM" <cmm@nospam.com> schrieb: VB 2005 supports different levels of visibility for 'Get' and 'Set'.> 1) The property is ReadOnly... like is often the case when you expose > collections or another complex object. You usually do this when you want > to maintain a particular instance of an object for whatever reason, allow > external classes to manipulate but not "switch" the object, but, inside > the class you should be able to do whatever you want with the object. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> As Johnny Carson used to say... "I did not know that."
Show quoteHide quote :-) Show quoteHide quote"Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message news:%231TobO%23NGHA.3284@TK2MSFTNGP14.phx.gbl... > "CMM" <cmm@nospam.com> schrieb: >> 1) The property is ReadOnly... like is often the case when you expose >> collections or another complex object. You usually do this when you want >> to maintain a particular instance of an object for whatever reason, allow >> external classes to manipulate but not "switch" the object, but, inside >> the class you should be able to do whatever you want with the object. > > VB 2005 supports different levels of visibility for 'Get' and 'Set'. > > -- > M S Herfried K. Wagner > M V P <URL:http://dotnet.mvps.org/> > V B <URL:http://classicvb.org/petition/> On Wed, 22 Feb 2006 20:10:11 +0100, "Herfried K. Wagner [MVP]"
<hirf-spam-me-here@gmx.at> wrote: >"CMM" <cmm@nospam.com> schrieb: Like this?>> 1) The property is ReadOnly... like is often the case when you expose >> collections or another complex object. You usually do this when you want >> to maintain a particular instance of an object for whatever reason, allow >> external classes to manipulate but not "switch" the object, but, inside >> the class you should be able to do whatever you want with the object. > >VB 2005 supports different levels of visibility for 'Get' and 'Set'. --- Private m_MyValue As Integer Public Property MyValue() As Integer Get Return m_MyValue End Get Private Set(ByVal value As Integer) m_MyValue = value End Set End Property --- Thank you. Just looked it up in the documentation. I don't think I would ever have known about this possibility unless someone pointed it out to me. Don't think I have seen its usage in any source samples I have come across, but this looks useful. /JB
Show quote
Hide quote
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb: Well, this is possible since VB 2005 and not supported by VB.NET 2002/2003.>>VB 2005 supports different levels of visibility for 'Get' and 'Set'. > > Like this? > --- > Private m_MyValue As Integer > Public Property MyValue() As Integer > Get > Return m_MyValue > End Get > Private Set(ByVal value As Integer) > m_MyValue = value > End Set > End Property > --- > > Don't think I have seen its usage in any source > samples I have come across, but this looks useful. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> Herfried,
I had to look 3 times before I saw it, you know probably what the intelisence gives back on such a property? Cor "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> schrieb: Sorry, I cannot follow you...> I had to look 3 times before I saw it, you know probably what the > intelisence gives back on such a property? -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> >I guess the assumption is that the class should know not to give a private In the interest of maintainability, if performance is not an issue,>member an "invalid" value that would otherwise not be possible using the >Accessor.... and if it does do so, it's doing it *knowingly.* standardizing on going through the accessor all the time might not be a bad idea: Could catch a few programming errors when the class is modified later. Suppose we have an uninitialized ArrayList member variable and the accessor knows that it should be created on first access. Using the member variable directly, one would have to make this check all the places it is being used, unless - for some reason - it is known that it has already been created at whatever point it is being used - something that would require a greater knowledge of the class than just the function being written/modified. >Furthermore, it depends on what the class *does* IMHO, a "Property Accesor Yes, I am beginning to firmly believe that the answer to the whole>Only" class might work well for regular ol' entity classes that represent >"data" (like a Person class) but not so much for a Custom Control, Form, or >other "action" oriented class that does more than just house information. debate is: "It depends". I have learned a couple of things today. Regards, JB "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message <snip>Could catch a few programming errors whennews:4afpv1p7a0ba9v3mgds3ig489ahctl4dpg@4ax.com... > the class is modified later. Suppose we have an uninitialized I'm a strong advocate for initializing in the declaration (and so is MS in > ArrayList member variable and the accessor knows that it should > be created on first access. <snip> their guidelines and the entire world outside of VB). 'arrays should be initialized Private myArray As Integer() = {} 'objects should be initialized (most of the time) Private myArrayList As New ArrayList 'and, yes, string objects should be initialized and not left as Nothing 'unless you actually need to do something particular with "Nothing." Private myStr As String = String.Empty This initialize-in-declaration is less less important IF you do NOT provide a default New() and instead *require* parameters to be passed into it ( like New(ary, arrayList, str) )
Show quote
Hide quote
"CMM" <cmm@nospam.com> schrieb: I think this depends on the particular case. Especially for strings an > <snip>Could catch a few programming errors when >> the class is modified later. Suppose we have an uninitialized >> ArrayList member variable and the accessor knows that it should >> be created on first access. <snip> > > I'm a strong advocate for initializing in the declaration (and so is MS in > their guidelines and the entire world outside of VB). > > 'arrays should be initialized > Private myArray As Integer() = {} > > 'objects should be initialized (most of the time) > Private myArrayList As New ArrayList > > 'and, yes, string objects should be initialized and not left as Nothing > 'unless you actually need to do something particular with "Nothing." > Private myStr As String = String.Empty empty string means something differently from a 'Nothing' reference. A 'Person' class with a 'FirstName' property of type 'String' could indicate an unknown first name if the property is set to 'Nothing' and an empty (no) first name if the property is set to an empty string. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/>
Show quote
Hide quote
"Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message Which is why I said "unless you actually need to do something particular news:eiU0oJ$NGHA.3936@TK2MSFTNGP12.phx.gbl... > "CMM" <cmm@nospam.com> schrieb: >> I'm a strong advocate for initializing in the declaration (and so is MS >> in their guidelines and the entire world outside of VB). >> >> 'arrays should be initialized >> Private myArray As Integer() = {} >> >> 'objects should be initialized (most of the time) >> Private myArrayList As New ArrayList >> >> 'and, yes, string objects should be initialized and not left as Nothing >> 'unless you actually need to do something particular with "Nothing." >> Private myStr As String = String.Empty > > I think this depends on the particular case. Especially for strings an > empty string means something differently from a 'Nothing' reference. A > 'Person' class with a 'FirstName' property of type 'String' could indicate > an unknown first name if the property is set to 'Nothing' and an empty > (no) first name if the property is set to an empty string. with 'Nothing.'" Nonetheless, I'd prefer to use DBNull in the scenerio you outline. I have never (well, maybe once with XML files ;-) )had to use Nothing.String for anything. Nothing does NOT mean "missing data"(!... well it could if you as the programmer wanted it to).... it means "uninitialized value." From MSDN: "The System.DBNull value indicates that the Object represents missing or nonexistent data. DBNull is not the same as Nothing, which indicates that a variable has not yet been initialized. DBNull is also not the same as a zero-length string (""), which is sometimes referred to as a null string."
Show quote
Hide quote
"CMM" <cmm@nospam.com> schrieb: IMO it simply means "variable not pointing to an instance" without further >>> I'm a strong advocate for initializing in the declaration (and so is MS >>> in their guidelines and the entire world outside of VB). >>> >>> 'arrays should be initialized >>> Private myArray As Integer() = {} >>> >>> 'objects should be initialized (most of the time) >>> Private myArrayList As New ArrayList >>> >>> 'and, yes, string objects should be initialized and not left as Nothing >>> 'unless you actually need to do something particular with "Nothing." >>> Private myStr As String = String.Empty >> >> I think this depends on the particular case. Especially for strings an >> empty string means something differently from a 'Nothing' reference. A >> 'Person' class with a 'FirstName' property of type 'String' could >> indicate an unknown first name if the property is set to 'Nothing' and an >> empty (no) first name if the property is set to an empty string. > > Which is why I said "unless you actually need to do something particular > with 'Nothing.'" Nonetheless, I'd prefer to use DBNull in the scenerio you > outline. I have never (well, maybe once with XML files ;-) )had to use > Nothing.String for anything. Nothing does NOT mean "missing data"(!... > well it could if you as the programmer wanted it to).... it means > "uninitialized value." semantics. However, it's possible to assign further semantics to variables pointing to 'Nothing'. > From MSDN: I think the sentence "indicates that a variable not yet been initialized" is > "The System.DBNull value indicates that the Object represents missing or > nonexistent data. DBNull is not the same as Nothing, which indicates that > a variable has not yet been initialized. DBNull is also not the same as a > zero-length string (""), which is sometimes referred to as a null string." unfortunate. Variables can even be initialized with 'Nothing' or can be set to 'Nothing' later on while the program is executing. The documentation for 'Nothing' contains a more appropriate description: "If the variable is of a reference type — that is, an object variable — 'Nothing' means the variable is not associated with any object". Using DBNull is not always an option, for example, it cannot be directly assigned to a property of type 'String'. It's a pretty obvious observation that 'DBNull.Value' is not the same as a 'Nothing' reference or an empty string. BTW: I have rarely seen the term "null string" for a zero-length (empty) string. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> > string. BTW: I have rarely seen the term "null string" for a zero-length Yeah. Me either.> (empty) string. NullString is yet ANOTHER thing... at least classically in VB.Classic... where vbNullString is used to pass C null-terminated empty strings to API's. I don't disagree with your NothingString comments either. But, I don't think I have ever encountered a situation where a dependency set my strings back to Nothing. IMO, NothingStrings' usefulness is extremely rare and specialized. Using them or not taking care to avoid them leads to needless fragility in complex applications. I'm NOT saying that they're useless.... just that their usefulness is rare. On Wed, 22 Feb 2006 15:12:37 -0500, "CMM" <cmm@nospam.com> wrote: I must go read that. Suppose the initializations are independent,>"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message >news:4afpv1p7a0ba9v3mgds3ig489ahctl4dpg@4ax.com... ><snip>Could catch a few programming errors when >> the class is modified later. Suppose we have an uninitialized >> ArrayList member variable and the accessor knows that it should >> be created on first access. <snip> > >I'm a strong advocate for initializing in the declaration (and so is MS in >their guidelines and the entire world outside of VB). such as Dim _myA As Integer = 2 Dim _myB As Integer = _myA * 2 Dim _myC As Integer = _myA + _myB you cannot just change the order of declarations, but if that sequence of initializations was made in a code block, you could swap them around all you liked, as long as the sequence in the code block remained the same. >'arrays should be initialized Suppose we are dealing with a more complex (and expensive) object>Private myArray As Integer() = {} > >'objects should be initialized (most of the time) >Private myArrayList As New ArrayList which might not be needed during the lifetime of the instance of the class. Would you want to initialize such an object at declaration time or on first use? In VB6, "Dim X As New SomeObject" meant that the instance X was only created if it was referenced - something that went against the general recommendations for performance reasons (every reference to X was wrapped in code checking for the existence of X behind the scenes, which would bloat the compiled .exe), but for *expensive* objects, I still think a similar pattern has its uses. I think FxCop by default warns about unnecessary initialization, i.e. Integer = 0, Boolean = False, etc. Something I'm not sure I agree with, since I like all my initializations to be explicit - whether at declaration time or in an initialization code block. /JB > Suppose we are dealing with a more complex (and expensive) object <snip>> which might not be needed during the lifetime of the instance of the > class. Would you want to initialize such an object at declaration time > or on first use? In VB6, "Dim X As New SomeObject" meant that the The question to ask in that case is "why is this variable at the method level?" Method level variables are usually the lazy programmers way of passing around data (bad code!) instead of as parameters. Having said that, I can see what you're saying. Like with everything else, no rule is absolute. There are clearly cases (in Property Accessor/ Value variables) where not initializing them is *intentionally* part of the design. Keep in mind though that object creation (unless it does some creepy IO in its constructor) is in no way expensive in VB.NET. A class with 1000 lines of code takes the same amount of time to instantiate as a class with 2 lines of code. (I'm talking method/code here, not data). VB.Classic had problems because of ref counting and stuff like that.... but even back then the "expense" of creating objects (as opposed to say structures) was way overhyped IMO. In. .NET, the expense (even for big complex classes) is virtually 0. Inside methods, the pattern is even clearer. Objects should be Dim'd exactly when they are needed rather than at the top of the method as was the VB.Classic practice. If their reference is based on a conditional then it's ok to create them unitialized and then set right afterwards. But if their value is known and not condition based they should always be initialized. Correct Usage Patterns (arguably) Dim o As New SomeClass --- Dim o As SomeClass = SomeObjA --- Dim o As SomeClass If someConditional Then o = SomeObjA Else o = SomeObjB End If --- For Each o As SomeClass In SomeCollection ... Next o --- If someConditional Then Dim o As New SomeClass ... End If 'object instantly goes of scope Show quoteHide quote "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message news:in5qv1t2jnt74814uf0afvd2irmnpesepb@4ax.com... > On Wed, 22 Feb 2006 15:12:37 -0500, "CMM" <cmm@nospam.com> wrote: > >>"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message >>news:4afpv1p7a0ba9v3mgds3ig489ahctl4dpg@4ax.com... >><snip>Could catch a few programming errors when >>> the class is modified later. Suppose we have an uninitialized >>> ArrayList member variable and the accessor knows that it should >>> be created on first access. <snip> >> >>I'm a strong advocate for initializing in the declaration (and so is MS in >>their guidelines and the entire world outside of VB). > > I must go read that. Suppose the initializations are independent, > such as > > Dim _myA As Integer = 2 > Dim _myB As Integer = _myA * 2 > Dim _myC As Integer = _myA + _myB > > you cannot just change the order of declarations, but if that sequence > of initializations was made in a code block, you could swap them > around all you liked, as long as the sequence in the code block > remained the same. > >>'arrays should be initialized >>Private myArray As Integer() = {} >> >>'objects should be initialized (most of the time) >>Private myArrayList As New ArrayList > > Suppose we are dealing with a more complex (and expensive) object > which might not be needed during the lifetime of the instance of the > class. Would you want to initialize such an object at declaration time > or on first use? In VB6, "Dim X As New SomeObject" meant that the > instance X was only created if it was referenced - something that went > against the general recommendations for performance reasons > (every reference to X was wrapped in code checking for the existence > of X behind the scenes, which would bloat the compiled .exe), but for > *expensive* objects, I still think a similar pattern has its uses. > > I think FxCop by default warns about unnecessary initialization, i.e. > Integer = 0, Boolean = False, etc. Something I'm not sure I agree > with, since I like all my initializations to be explicit - whether at > declaration time or in an initialization code block. > > /JB > > >
Show quote
Hide quote
On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cmm@nospam.com> wrote: I was thinking about a usercontrol wrapping a tabcontrol with a number>> Suppose we are dealing with a more complex (and expensive) object >> which might not be needed during the lifetime of the instance of the >> class. Would you want to initialize such an object at declaration time >> or on first use? In VB6, "Dim X As New SomeObject" meant that the ><snip> > >The question to ask in that case is "why is this variable at the method >level?" Method level variables are usually the lazy programmers way of >passing around data (bad code!) instead of as parameters. Having said that, >I can see what you're saying. Like with everything else, no rule is >absolute. There are clearly cases (in Property Accessor/ Value variables) >where not initializing them is *intentionally* part of the design. of tabpages, each of which contains a usercontrol wrapping the controls for that page. In some cases, initializing all pages at once is desired (i.e. long wait the first time the tabcontrol is displayed). In other cases, we want to display the tabcontrol as quickly as possible, but only initialize the individual tabpages as they are being selected by the user. Then, of course, there are the high-volume cases where tens of thousands instances of a class need to be instantiated in a short span of time and where every little unnecessary instantiation takes time (e.g. if the instantiated object creates a new GUID or similar). I agree with the rest of your statements about usage patterns inside methods. I am only talking about the class' members. /JB
Show quote
Hide quote
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:bssqv1l555r4fqai9vd3pvlsktkt5b2ppo@4ax.com... > On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cmm@nospam.com> wrote: > >>> Suppose we are dealing with a more complex (and expensive) object >>> which might not be needed during the lifetime of the instance of the >>> class. Would you want to initialize such an object at declaration time >>> or on first use? In VB6, "Dim X As New SomeObject" meant that the >><snip> >> >>The question to ask in that case is "why is this variable at the method >>level?" Method level variables are usually the lazy programmers way of >>passing around data (bad code!) instead of as parameters. Having said >>that, >>I can see what you're saying. Like with everything else, no rule is >>absolute. There are clearly cases (in Property Accessor/ Value variables) >>where not initializing them is *intentionally* part of the design. > > I was thinking about a usercontrol wrapping a tabcontrol with a number > of tabpages, each of which contains a usercontrol wrapping the > controls for that page. In some cases, initializing all pages at once > is desired (i.e. long wait the first time the tabcontrol is > displayed). > In other cases, we want to display the tabcontrol as quickly as > possible, but only initialize the individual tabpages as they are > being selected by the user. > > Then, of course, there are the high-volume cases where tens of > thousands instances of a class need to be instantiated in a short > span of time and where every little unnecessary instantiation takes > time (e.g. if the instantiated object creates a new GUID or similar). > > I agree with the rest of your statements about usage patterns inside > methods. I am only talking about the class' members. > > /JB > > Sorry... hit send too soon.
Anyway. I see what you mean. In the first example "the initialize as soon as possible" idea doesn't extend to elements of a collection (your tab page contents). Though it does apply to the collection instance itself (it can instantiated, but empty and filled as needed). Forms and Controls are tricky because Painting/Redraw is a big bottleneck as is the Win32 Messaging Subsystem. That's why they have those SuspendLayout and BeginUpdate mechanisms.... In the second example, there's no doubt some rare classes might necessitate a first-use sort of mechanism on some of their Property Accessors and underlying values... though I venture to say this is rarer than you think and needs study before you actually spend time doing it. For instance.... using GUID your example.... on my machine and in debug mode it takes 15ms to create 10,000 guid's and add them to an ArrayList! That's less than a blink of an eye. Show quoteHide quote "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message news:bssqv1l555r4fqai9vd3pvlsktkt5b2ppo@4ax.com... > On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cmm@nospam.com> wrote: > >>> Suppose we are dealing with a more complex (and expensive) object >>> which might not be needed during the lifetime of the instance of the >>> class. Would you want to initialize such an object at declaration time >>> or on first use? In VB6, "Dim X As New SomeObject" meant that the >><snip> >> >>The question to ask in that case is "why is this variable at the method >>level?" Method level variables are usually the lazy programmers way of >>passing around data (bad code!) instead of as parameters. Having said >>that, >>I can see what you're saying. Like with everything else, no rule is >>absolute. There are clearly cases (in Property Accessor/ Value variables) >>where not initializing them is *intentionally* part of the design. > > I was thinking about a usercontrol wrapping a tabcontrol with a number > of tabpages, each of which contains a usercontrol wrapping the > controls for that page. In some cases, initializing all pages at once > is desired (i.e. long wait the first time the tabcontrol is > displayed). > In other cases, we want to display the tabcontrol as quickly as > possible, but only initialize the individual tabpages as they are > being selected by the user. > > Then, of course, there are the high-volume cases where tens of > thousands instances of a class need to be instantiated in a short > span of time and where every little unnecessary instantiation takes > time (e.g. if the instantiated object creates a new GUID or similar). > > I agree with the rest of your statements about usage patterns inside > methods. I am only talking about the class' members. > > /JB > > Carlos,
Although the sample from Joergen is inviting to pass the checking in the property rules by using the method (therefore my answer) do I use myself forever the private members inside the class. The main reason is that I hate it when I am debugging step by step to see the code go up and down. Cor Yeah me too!!!
Though I guess if you 1) Use Me. on Accessors and 2) camelCase on vars it's A LOT easier to tell at a glance when you're about to step *into* an Accessor and hit F10 to step over it. :-) Show quoteHide quote "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message news:ej7Q1SGOGHA.1460@TK2MSFTNGP10.phx.gbl... > Carlos, > > Although the sample from Joergen is inviting to pass the checking in the > property rules by using the method (therefore my answer) do I use myself > forever the private members inside the class. > > The main reason is that I hate it when I am debugging step by step to see > the code go up and down. > > Cor > On Thu, 23 Feb 2006 11:35:52 +0100, "Cor Ligthert [MVP]"
<notmyfirstn***@planet.nl> wrote: >Carlos, You can decorate your property Get/Sets with the> >Although the sample from Joergen is inviting to pass the checking in the >property rules by using the method (therefore my answer) do I use myself >forever the private members inside the class. > >The main reason is that I hate it when I am debugging step by step to see >the code go up and down. > >Cor > DebuggerStepThrough attribute to get around that, so that in itself is not an argument for going the direct route. Problem is, with properties, the attribute has to be applied to the Get function and Set method individually, rather than the whole property itself, which messes up the indentation and makes the code less readable, i.e.: Public Property DragForm() As Boolean <System.Diagnostics.DebuggerStepThrough()> _ Get Return _DragForm End Get <System.Diagnostics.DebuggerStepThrough()> _ Set(ByVal value As Boolean) If _DragForm = value Then Return End If _DragForm = value End Set End Property Other than disabling the auto-formatting of the source, I don't see how this problem can be solved. :( /JB "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb: Well, that's what 'WeakReference' is basically for, except that its behavior > In VB6, "Dim X As New SomeObject" meant that the > instance X was only created if it was referenced - something that went > against the general recommendations for performance reasons > (every reference to X was wrapped in code checking for the existence > of X behind the scenes, which would bloat the compiled .exe), but for > *expensive* objects, I still think a similar pattern has its uses. is different in matters of object destruction. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> On Thu, 23 Feb 2006 10:54:19 +0100, "Herfried K. Wagner [MVP]"
<hirf-spam-me-here@gmx.at> wrote: >"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb: WeakReference - as I understand it - is used for tracking the state of>> In VB6, "Dim X As New SomeObject" meant that the >> instance X was only created if it was referenced - something that went >> against the general recommendations for performance reasons >> (every reference to X was wrapped in code checking for the existence >> of X behind the scenes, which would bloat the compiled .exe), but for >> *expensive* objects, I still think a similar pattern has its uses. > >Well, that's what 'WeakReference' is basically for, except that its behavior >is different in matters of object destruction. a previously created object which may or may not have been garbage collected, i.e. it can be used to figure out if an object is still alive and can be reused or if it needs to be recreated. I do not see where WeakReference applies to any objects that have not been created in the first place(?) /JB "Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb: I am wondering why you would bypass validation there. Especially if >>> Still, if the priority is *maintainability*, wouldn't it be best only >>> to use the direct access in the constructor only and the >>> property setter in all other cases? >> >>I /always/ set the property value through the property. > > The constructor is *the* one place where I normally would want > to initialize all the members directly, without any checks or > side effects, but come to think of it ... good point you made there. assigning property values through parameters of the constructor I'd recommend to use the accessor: \\\ Private m_Age As Integer Public Sub New(ByVal Age As String) Me.Age = Age End Sub Public Property Age() As Integer Get Return m_Age End Get Set(ByVal Value As Integer) If Value <= 0 Then Throw New ArgumentException(...) Else m_Age = Value End If End Set End Property /// I'd even call the accessor if I only assign a constant value because validation criteria may change over time. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> |
|||||||||||||||||||||||