Results 1 to 39 of 39

Thread: Zero-length or Nothing

  1. #1

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Zero-length or Nothing

    When ever I write functions that return Strings, I tend to return Nothing when the method in question has nothing to return and throwing exceptions is not necessary. Another alternative is to return a zero-length string. I want you guys to give your opinions: Is it better to return Nothing or a zero-length string. I've always wondered which would be the better practice and why.

    This of course can only apply to .Net(VB.Net/C# etc) and C/C++ as a zero-length string and a non-existent string are two distinct things where as in a language like VB6 there is no such distinction.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  2. #2
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Zero-length or Nothing

    Returning Nothing indicates that there is no answer. Returning a zero-length string indicates there is an answer, and the answer is a zero-length string.

    I fail to see why people get confused over this.

  3. #3

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    Returning Nothing indicates that there is no answer. Returning a zero-length string indicates there is an answer, and the answer is a zero-length string.

    I fail to see why people get confused over this.
    This was my thought as well yet while I can't remember any specific examples of this in the .Net Framework, I noticed that MS tends to avoid using null strings when they can as is the case with the Control class's Text property. You cannot set that to Nothing. It will always default to a zero-length string if you do. This is what made me wonder if it was an inherently bad practice to use null strings deliberately.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Zero-length or Nothing

    I don't fail to see why people get confused over THAT part. What gets me is that you may be getting a zero length string in BOTH cases. It isn't just the Text property that behaves in that odd fashion. I remember a thread from a few months back where it appeared that all strings set to Nothing were actually just zero length strings. Therefore, you might try something horrible like this:
    Code:
    Private SomeFunc() As String
     Return Nothing
    End Function
    
    Dim st1 As String = SomeFunc
    If st1 = string.Empty Then
     MessageBox.Show("It's just EMPTY")
    End If
    I know what I believe SHOULD happen, but without trying it, I'm not sure what actually WILL happen. I just remember that what happened wasn't what I expected.
    My usual boring signature: Nothing

  5. #5
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Zero-length or Nothing

    Quote Originally Posted by Niya View Post
    as is the case with the Control class's Text property. You cannot set that to Nothing. It will always default to a zero-length string if you do.
    That's because there is an answer to the question "What is this Control's text value?", it's just that the answer might be a zero-length string.

    Quote Originally Posted by Niya View Post
    This is what made me wonder if it was an inherently bad practice to use null strings deliberately.
    If you've considered the problem and decided that it is a situation that requires a null-value rather than an empty-value, then it is quite correct to return Nothing. However, you need to consider the problem with Nothings being allowed to creep through your logic - NullReferenceExceptions abound unless you wrap your code in intent-hiding null checks. I'd rather rely on higher level patterns, like the Maybe monad, or specific Null Objects.

  6. #6
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: Zero-length or Nothing

    If you've considered the problem and decided that it is a situation that requires a null-value rather than an empty-value, then it is quite correct to return Nothing.
    i do use it the same way. nothing would only be used to indicate a kind of special condition in the function otherwise the return value would always be a zero length string.

  7. #7
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Zero-length or Nothing

    To me, a return of Nothing is only used in the case where "no possible answer of any sort would be correct." I generally don't use that for strings, but do use it for methods that return objects when things go right, and Nothing would represent "no answer".
    My usual boring signature: Nothing

  8. #8
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: Zero-length or Nothing

    Whether you would return Nothing or a zero length string would depend on the application. How that is represented would depend, again, on the application.

    Essentially, Nothing indicates it is undefined. This can be useful when reading from a database, where Nothing would be completely valid.

    Why not frame the question with regards to zero length strings, verses a string with only spaces in it: what is the distinction? Why would one be valid, and the other not? This would be the same distinction between Nothing and zero length, would it not?

    Also see nullable types.
    "Ok, my response to that is pending a Google search" - Bucky Katt.
    "There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
    "Before you can 'think outside the box' you need to understand where the box is."

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Zero-length or Nothing

    By the way, I tried out the test I suggested in post #4, and got what I expected, though I don't think it is the way it should be. In that test, I have a function that returns Nothing. Therefore, st1 should be set to Nothing, and the If statement should crash, but it doesn't. In fact, st1 = String.Empty. Therefore, this whole discussion is moot, because you can't really return Nothing from a function that returns a string. You get an empty string whether you try to return Nothing or not.
    My usual boring signature: Nothing

  10. #10
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    Well, considering Strings are that strange "a value and yet a reference" hybrid object type, I wouldn't be surprised that there's something "funny" going on under the hood.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  11. #11
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: Zero-length or Nothing

    Therefore, st1 should be set to Nothing, and the If statement should crash, but it doesn't. In fact, st1 = String.Empty.
    but a If st1.Length = 0 Then does crash so returning nothing can indeed cause problems if the caller is not aware.

  12. #12
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: Zero-length or Nothing

    Based on Shaggy's code:

    Code:
    		Dim eq As Boolean = String.Equals(Nothing, String.Empty) ' False
    		eq = String.Equals(CStr(Nothing), String.Empty)	' False
    		eq = String.Equals(st1, String.Empty) ' False
    		eq = String.Equals(st1, CStr(Nothing)) ' TRUE
    		eq = String.Equals(Nothing, st1) ' TRUE
    		eq = (String.Empty Is Nothing) ' False
    		eq = st1 Is Nothing	' TRUE
    		eq = (st1 = String.Empty) ' False (Returns TRUE!)
    Strange results.

    The Equals operator appears to return an 'incorrect' result. The Equals Operator calls the Equals(a,b) shared method, according to Reflector, but doesn't return the same result, so something else is happening.
    "Ok, my response to that is pending a Google search" - Bucky Katt.
    "There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
    "Before you can 'think outside the box' you need to understand where the box is."

  13. #13

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    The Strings aren't the things behaving strangely, its the methods that behave strangely:-
    vbnet Code:
    1. '
    2.         Dim s As String = Nothing
    3.  
    4.         'Evaluates as empty even if nothing
    5.         If s = String.Empty Then
    6.             Debug.WriteLine("Empty")
    7.         End If
    8.  
    9.         'Throws a NullReference exception
    10.         'as any normal object would
    11.         Dim fs = s.First

    In any case I always use String.IsNullOrEmpty to evaluate strings that are expected to be empty or zero-length.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  14. #14
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Zero-length or Nothing

    It's probably just that the = operator is overloaded for the String class in an odd way such that Nothing is evaluated as String.Empty. That would be a shared method, so the compiler wouldn't complain about the fact that st1 was Nothing, as that wouldn't matter.
    My usual boring signature: Nothing

  15. #15

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    Quote Originally Posted by Shaggy Hiker View Post
    It's probably just that the = operator is overloaded for the String class in an odd way such that Nothing is evaluated as String.Empty. That would be a shared method, so the compiler wouldn't complain about the fact that st1 was Nothing, as that wouldn't matter.
    That was my thought too.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  16. #16
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Zero-length or Nothing

    Quote Originally Posted by SJWhiteley View Post
    Based on Shaggy's code:

    Code:
    		Dim eq As Boolean = String.Equals(Nothing, String.Empty) ' False
    		eq = String.Equals(CStr(Nothing), String.Empty)	' False
    		eq = String.Equals(st1, String.Empty) ' False
    		eq = String.Equals(st1, CStr(Nothing)) ' TRUE
    		eq = String.Equals(Nothing, st1) ' TRUE
    		eq = (String.Empty Is Nothing) ' False
    		eq = st1 Is Nothing	' TRUE
    		eq = (st1 = String.Empty) ' False (Returns TRUE!)
    Strange results.

    The Equals operator appears to return an 'incorrect' result. The Equals Operator calls the Equals(a,b) shared method, according to Reflector, but doesn't return the same result, so something else is happening.
    This is because:
    The Visual Basic compiler does not resolve the equality operator as a call to the Equality method. Instead, the equality operator wraps a call to the Operators.CompareString method.
    see: String.Equality Operator

    Edit: Based on Niya's OP, VB6 compatibility strikes again.

    Quote Originally Posted by Niya View Post
    ... a zero-length string and a non-existent string are two distinct things where as in a language like VB6 there is no such distinction.
    Last edited by TnTinMN; Sep 2nd, 2014 at 02:48 PM.

  17. #17
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: Zero-length or Nothing

    Quote Originally Posted by TnTinMN View Post
    This is because:
    see: String.Equality Operator

    Edit: Based on Niya's OP, VB6 compatibility strikes again.
    :/

    Yeah, read that thing again: it states it resolves to the "Equals" method then goes ahead and states that it doesn't [for VB]...
    "Ok, my response to that is pending a Google search" - Bucky Katt.
    "There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
    "Before you can 'think outside the box' you need to understand where the box is."

  18. #18
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Zero-length or Nothing

    I also see that it is insensitive to culture. They really should be more sensitive, don't you think? Heck, it's running on a PC, right?

    I suppose this might just be another nod to VB6 backwards compatibility. It's never a full-on bow, though. Nothing more than a nod.
    My usual boring signature: Nothing

  19. #19
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    Maybe it's never been to sensitivity training. I don't think I'veever seen VB at any of the training sessions I've been too... and having been in the military, I've been to plenty of sensitivity training sessions.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  20. #20
    Lively Member elielCT's Avatar
    Join Date
    Jun 2011
    Posts
    89

    Re: Zero-length or Nothing

    there are alot of articles written about this all over the place.. i had found a few interesting ones in http://www.dreamincode.net/forums/ and a few in http://stackoverflow.com/questions/1...n-empty-object.. but i think my favorite one was in http://www.codeproject.com/Articles/...ty-List-Instea

  21. #21
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Zero-length or Nothing

    Quote Originally Posted by elielCT View Post
    there are alot of articles written about this all over the place.. i had found a few interesting ones in http://www.dreamincode.net/forums/ and a few in http://stackoverflow.com/questions/1...n-empty-object.. but i think my favorite one was in http://www.codeproject.com/Articles/...ty-List-Instea
    I haven't looked at the others but that last one is not really specifically relevant to this thread. Whether or not to return an empty collection or null is not the same question as whether to return an empty string or null.

    For example, if you have a list of names and I say that I want you to give me a list of all those that start with "A" then, if no names star with "A" then I should get an empty list, not nothing at all. If I ask for a list then I should get list and if that list contains no items then so be it.

    On the other hand, if you were to ask me for my father's middle name then I would give you nothing, not a string with no characters in it. My father doesn't have a middle name at all so you get nothing. Noone has a middle name with no letters in it.

    The specifics would depend on the particular situation but, personally, I subscribe to the empty list over null but null over the empty string in most cases.

  22. #22

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    Its funny that you guys should mention empty lists. I pretty much agree with jmc's thinking. I've always been very clear about how I handle this. When the method in question was passed valid parameters or its operation went smoothly but there were no results then I would return an empty list/collection/array but if there was some kind of abnormality during its execution like an exception or something, I return null if I decide that throwing an exception is not warranted. Its not so clear cut with me on string returns hence the creation of this thread.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  23. #23

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    Quote Originally Posted by elielCT View Post
    Although they didn't really address strings, this was an interesting read. I especially liked the idea where the guy suggested using a callback whenever an operation returns a valid result and not using it when the operation cannot return a valid answer. It avoids null checking code. Personally, I wouldn't use such an approach as its too bulky in my opinion but I did find it clever nonetheless.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  24. #24
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: Zero-length or Nothing

    Code:
    suggested using a callback whenever an operation returns a valid result and not using it when the operation cannot return a valid answer.
    gahh, that sounds super complicated. if you really want a clear approach that i'd suggest you go with the same pattern as TryParse uses: return true/false for success and the result in a byref parameter

  25. #25

    Thread Starter
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Zero-length or Nothing

    Quote Originally Posted by digitalShaman View Post
    if you really want a clear approach that i'd suggest you go with the same pattern as TryParse uses: return true/false for success and the result in a byref parameter
    There is a certain elegance to that method. I use it sometimes but only when I have a function that must return more than one value and declaring an extra class seems overkill. My rational is that since I'm returning the values I want through the parameters I might as well use the function's return to indicate failure or success by use of a Boolean.

    In general though, I hate returning values through parameters because it forces you to always declare a variable for the return whenever you need to call the method in question. You can't do cute stuff like:
    vbnet Code:
    1. If Func(someValue) = 1 Then
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  26. #26
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Zero-length or Nothing

    It's a typically functional style of writing code, which C# is increasingly leaning towards. If you've written any Javascript in the last 5 years you'll be very used to this pattern as well. Not so sure it will sit well with VB because of the verbosity of passing functions as parameters compared to C# et al.

    [Edit: Also, I'd much prefer a TryParse that took a callback parameter. Consider the 99% use case for TryXXX:

    vbnet Code:
    1. If something.TryParse(output) Then
    2.     output.DoSomething
    3. End If

    compared to:

    vbnet Code:
    1. something.TryParse(Sub (output) output.DoSomething)

    or if it's worth creating it's own method for:
    vbnet Code:
    1. something.TryParse(AddressOf DoSomethingWithOutput)
    2.  
    3. ' ...
    4. Sub DoSomethingWithOutput(output As Output)
    5.     output.DoSomething
    6. End Sub

    Oh look: your If statement has disappeared! (that's a good thing, btw)
    Last edited by Evil_Giraffe; Sep 3rd, 2014 at 10:27 AM.

  27. #27
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Zero-length or Nothing

    Quote Originally Posted by digitalShaman View Post
    Code:
    suggested using a callback whenever an operation returns a valid result and not using it when the operation cannot return a valid answer.
    gahh, that sounds totally new. if you really want a familiar approach that i'd suggest you go with the same pattern as TryParse uses: return true/false for success and the result in a byref parameter
    FTFY. There is nothing unclear or inelegant about the approach, you're just not used to it. You'd better get used to it though, because as the languages and frameworks increasingly adopt asynchronous models, this style is going to be forced on you in more and more situations.

  28. #28
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    FTFY. There is nothing unclear or inelegant about the approach, you're just not used to it. You'd better get used to it though, because as the languages and frameworks increasingly adopt asynchronous models, this style is going to be forced on you in more and more situations.
    Although it is used for asynchronous operations, and, as you note, more common as asynchronicity becomes a norm, it doesn't mean it's appropriate for this situation. Callbacks imply an asynchronous operation.
    "Ok, my response to that is pending a Google search" - Bucky Katt.
    "There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
    "Before you can 'think outside the box' you need to understand where the box is."

  29. #29
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    710

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    FTFY. There is nothing unclear or inelegant about the approach, you're just not used to it. You'd better get used to it though, because as the languages and frameworks increasingly adopt asynchronous models, this style is going to be forced on you in more and more situations.
    I'd say it's terribly inelegant. Bored programmers looking for more complex ways of doing things...
    David Anton
    Convert between VB, C#, C++, & Java
    www.tangiblesoftwaresolutions.com

  30. #30
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    ..[Edit: Also, I'd much prefer a TryParse that took a callback parameter. ...
    How about something like this?
    VB.Net Code:
    1. Module GenericParse
    2.    Private tryParseMethods As New Dictionary(Of RuntimeTypeHandle, Reflection.MethodInfo)
    3.    Private typeString As Type = GetType(String)
    4.  
    5.    Public Sub TryParse(Of T)(s As String, del As Action(Of T))
    6.       Dim typeT As Type = GetType(T)
    7.       Dim rtHandle As RuntimeTypeHandle = typeT.TypeHandle
    8.       Dim mi As Reflection.MethodInfo
    9.       If Not tryParseMethods.ContainsKey(rtHandle) Then
    10.          mi = typeT.GetMethod("TryParse",
    11.                               Reflection.BindingFlags.Public Or Reflection.BindingFlags.Static,
    12.                               Type.DefaultBinder,
    13.                               New Type() {typeString, typeT.MakeByRefType},
    14.                               Nothing)
    15.          If mi Is Nothing Then
    16.             Throw New Exception("Could not find TryParse on type: " & typeT.FullName)
    17.          Else
    18.             tryParseMethods.Add(rtHandle, mi)
    19.          End If
    20.       Else
    21.          mi = tryParseMethods(rtHandle)
    22.       End If
    23.  
    24.       Dim ret As T
    25.       Dim args As Object() = {s, ret}
    26.       If DirectCast(mi.Invoke(Nothing, args), Boolean) Then
    27.          ret = DirectCast(args(1), T)
    28.          del.Invoke(ret)
    29.       End If
    30.    End Sub
    31. End Module
    Sample usage:
    Code:
    TryParse(Of Int32)("3", Sub(val As Int32)
                               MsgBox(val.ToString())
                            End Sub
                      )

  31. #31
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    great... now how do I get that value so I can do something with it? it's stuck inside the anon sub. We're back to having to create a varaible, set it inside the anon sub... why not just call Integer.TryParse directly at that point? I think when you have achieved this point, you're engineering for the sake of engineering. All that's happened (at least how it appears to me) is that it's just another gee-wizz widget that does the exact same thing as Integer.TryParse with virtually no benefit.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  32. #32
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Zero-length or Nothing

    Quote Originally Posted by techgnome View Post
    great... now how do I get that value so I can do something with it? it's stuck inside the anon sub. We're back to having to create a varaible, set it inside the anon sub... why not just call Integer.TryParse directly at that point? I think when you have achieved this point, you're engineering for the sake of engineering. All that's happened (at least how it appears to me) is that it's just another gee-wizz widget that does the exact same thing as Integer.TryParse with virtually no benefit.

    -tg
    It was not designed to address your concerns, EG asked for callback TryParse and I just presented a way of accomplishing that. I really do not care what his goal is, but since he posited the need I'm sure he has his reasons. As far as result being buried in a compiler generate method, you could just as easily pass it a delegate to any method with the proper signature.

    Use whatever tool lets you best accomplish the task at hand.

  33. #33
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    I guess my point was that 99% of the time I'm using TryParse I'm validating input of some kind, where it is extraordinarily linear, callbacks don't make much sense. Even a delegate wouldn't help. Makes me wonder what 99% cases EG is working with. Don't get me wrong, I'm not knocking your solution (if I was I didn't meant to an I apologize) but I question its necessity. in 99% of my cases, I'm using Decimal.TryPArse, Integer.TryParse or Date.TryParse to get a value from a string (user input or file). Unless he's implementing it in a custom class - that's the only way his code could even come close to working; the syntax is type.TryParse(input, byref output, cultureInfo) as Boolean ....

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  34. #34
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Zero-length or Nothing

    I think that we will need to see if he offers a usage case. Personally, I do not foresee ever needing this type of functionality, but the main reason I participate in a forum to to see if I can learn new techniques and/or new ways of looking at problem.

  35. #35
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    Quote Originally Posted by TnTinMN View Post
    I think that we will need to see if he offers a usage case. Personally, I do not foresee ever needing this type of functionality, but the main reason I participate in a forum to to see if I can learn new techniques and/or new ways of looking at problem.
    Well now that's just silly. Why would you do that? That would cause your brain to fillup with useless things and you'd start to forget the things that are... umm.... ugh... what's that word? Urg...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  36. #36
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Zero-length or Nothing

    Quote Originally Posted by techgnome View Post
    I guess my point was that 99% of the time I'm using TryParse I'm validating input of some kind, where it is extraordinarily linear, callbacks don't make much sense.
    I'm not just talking about TryParse. I'm talking about the more general TryXXX Pattern. I work with rather large information processing systems that don't take a huge relative amount of user input (and where they do, the validation of it and conversion into useful types happens well away from application logic). There are a large class of problems that we face that boil down to "Try to do X; if that succeeds pipe the output into this function, if it fails pipe the error over here". If we repeated the boilerplate "If Blah.TryWhatever(input, input, ..., output) Then SuccessFunc(output) Else ErrorFunc() End If" (or actually, the C# equivalent with exception handling baked in and so on) we'd be at the risk of introducing errors each time the pattern was repeated. If you call eliminating the repetitive boilerplate to the infrastructure "engineering for the sake of engineering" then I'm going to have to assume that you aren't dealing with anything like the complexity that exists in the system I'm currently working on. This is actually "engineering for the sake of getting some useful work done".

    Also, I fail to see how it wouldn't apply to TryParse in any case. Yes, the output is now stuck in the function. But with TryParse it's still stuck in a function... you can put everything that was in that outer function in the callback function, no? I think you may have missed the point of the continuation callback.

    And @TnTinMN, that's great, but I wasn't actually asking for a method, we have plenty in our codebase already. I was more wishing that Microsoft had gone with the callback style of interface over the ByRef and return a Boolean, but never mind. Also, I'd personally avoid using Reflection and add typed methods as and when I needed them for each type. There's not many basic types you'd want to TryParse, and the method itself is simply implement the TryParse calling pattern, but call the passed in function on success instead, so it's probably easier to write and eye-ball for correctness than your reflection approach?

  37. #37
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Zero-length or Nothing

    Quote Originally Posted by digitalShaman View Post
    Code:
    suggested using a callback whenever an operation returns a valid result and not using it when the operation cannot return a valid answer.
    gahh, that sounds super complicated. if you really want a clear approach that i'd suggest you go with the same pattern as TryParse uses: return true/false for success and the result in a byref parameter
    The thing about that is that you then have to test the value returned by the TryParse-like method and that is really no different to testing whether a return value is null.

  38. #38
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,537

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    Also, I fail to see how it wouldn't apply to TryParse in any case. Yes, the output is now stuck in the function. But with TryParse it's still stuck in a function... you can put everything that was in that outer function in the callback function, no? I think you may have missed the point of the continuation callback.
    No, I completely get it... and I see in some cases where it could be an advantage... in other case it simply won't work. Period. Example, my client's don't give one wit that "2014-09-03" is parsible into a date... but they do give a crap that "xyds-09-01" isn't... which means I'm doing If this succeeds, great ELSE notify the user, or maybe I need to set it to a default value... so unless you're going to account for BOTH a success and a fail callback... I'm better off with using Date.TryParse and using an if then to test the result. My other point was that on trivial objects, such as we're talking about - integers, dates, etc - the call back method is more than trivial... and requires some setup... Now, since you brought up the complex object processing, I'm fairly certain that what ever object you're parsing is not a standard object, then what difference does it make what MS did with TryParse anywhere else? Build the callback into your object and call it a day. Which is what it sounds like you did. Problem solved.

    Besides, NOTHING was ever said about complex types. Your assetrion that 99% of the TryXXX pattern fell a particular way is what irked me... because for me that's 1% of the cases... the other 99% are of the failure type, only when dealing with basic types. Deal with complex data types too... all the time... but we don't "TryParse" them... we build it into the Constructor... and the object will be created or it won't (or more typically it'll be created with default data, or a list of errors).

    6 of one 1/2 dozen of another I suppose.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  39. #39
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Zero-length or Nothing

    Quote Originally Posted by Evil_Giraffe View Post
    ..And @TnTinMN, that's great, but I wasn't actually asking for a method, we have plenty in our codebase already. I was more wishing that Microsoft had gone with the callback style of interface over the ByRef and return a Boolean, but never mind. Also, I'd personally avoid using Reflection and add typed methods as and when I needed them for each type. There's not many basic types you'd want to TryParse, and the method itself is simply implement the TryParse calling pattern, but call the passed in function on success instead, so it's probably easier to write and eye-ball for correctness than your reflection approach?
    This discussion has brought up differing viewpoints of what is common and what is not based on what the individual's work requires. I feel that the same is the case of what is easy to eye-ball for correctness. To me a single template that can generate various methods makes sense versus writing each method. Reflection can be difficult to understand if you do not use often, but the same can be said of any advanced technique. For example, many find Linq to be totally non-comprehensible whereas others think that it should be used everywhere. This is all a matter of perspective and I am not looking to get into a religious war over what is better.

    Also when I slapped that code together earlier today, I envisioned that you may have a class with its own parse method such as something like this:
    Code:
    Public Class Fred
       Public A As String
       Public B As Int32
       Private Sub New()
       End Sub
    
       Public Shared Function TryParse(s As String, ByRef returnValue As Fred) As Boolean
          Dim passed As Boolean
          Try
             Dim parts() As String
             parts = s.Split(","c)
             If parts.Length = 2 Then
                returnValue.A = parts(0)
                passed = Int32.TryParse(parts(1), returnValue.B)
             End If
          Catch ex As Exception
             ' eat exception
          End Try
          Return passed
       End Function
    End Class
    Unfortunately, I neglected to make accommodation in that code to handle instantiating non-ValueTypes. Here is a revised version that includes that code for whoever is interested.

    Code:
    Module GenericParse
       Private tryParseMethods As New Dictionary(Of RuntimeTypeHandle, Reflection.MethodInfo)
       Private tryParseConstructors As New Dictionary(Of RuntimeTypeHandle, Reflection.ConstructorInfo)
       Private typeString As Type = GetType(String)
    
       Public Sub TryParse(Of T)(s As String, del As Action(Of T))
          Dim typeT As Type = GetType(T)
          Dim rtHandle As RuntimeTypeHandle = typeT.TypeHandle
          Dim mi As Reflection.MethodInfo
          Dim ci As Reflection.ConstructorInfo
    
          If typeT.IsInterface Then
             Throw New NotSupportedException("Interfaces are not a supported type")
          End If
    
          If tryParseMethods.ContainsKey(rtHandle) Then
             mi = tryParseMethods(rtHandle)
          Else
             mi = typeT.GetMethod("TryParse",
                                  Reflection.BindingFlags.Public Or Reflection.BindingFlags.Static,
                                  Type.DefaultBinder,
                                  New Type() {typeString, typeT.MakeByRefType},
                                  Nothing)
             If mi Is Nothing Then
                Throw New Exception("Could not find TryParse on type: " & typeT.FullName)
             Else
                tryParseMethods.Add(rtHandle, mi)
             End If
          End If
    
          Dim ret As T
          If typeT.IsClass Then ' get constructor for class
             If tryParseConstructors.ContainsKey(rtHandle) Then
                ci = tryParseConstructors(rtHandle)
             Else
                ci = typeT.GetConstructor(Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance,
                                          Type.DefaultBinder,
                                          Type.EmptyTypes,
                                          Nothing)
                If ci Is Nothing Then
                   Throw New Exception("Could not find default constructor on type: " & typeT.FullName)
                Else
                   tryParseConstructors.Add(rtHandle, ci)
                End If
             End If
             ret = CType(ci.Invoke(Nothing), T)
          End If
    
          Dim args As Object() = {s, ret}
          If DirectCast(mi.Invoke(Nothing, args), Boolean) Then
             ret = CType(args(1), T)
             del.Invoke(ret)
             ' or
             'del.BeginInvoke(ret, Nothing, Nothing)
          End If
       End Sub
    End Module

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width