Ignoring the Class System


  • Trolleybus Mechanic

                    For Each current In Controls
                        Select Case current.GetType.Name
                            Case "ShortTextLine"
    

    Object type checking: You're :doing_it_wrong:



  • @Lorne_Kates said:

    You're :doing_it_wrong:

    How dare you insult me like that.



  • From something made where I work:

    If phUDF.HasControls Then
        For Each ctl As System.Web.UI.Control In phUDF.Controls
            Select Case ctl.GetType.Name.ToLower
                Case "textbox"
    

  • BINNED

    At least it has ToLower which makes it 10 times better!

    I'm kinda wondering if there's a SO answer promoting that or is it just a common antipattern?


  • Trolleybus Mechanic

    @aliceif said:

    ToLower

    That and .ToUpper are lovely little canaries I see all the time.

    👦 Excuse me, other dev. I couldn't help but notice this ToLower everywhere. Why not use Equals(otherString, StringComparison.InvariantCultureIgnoreCase) ?
    👻 WAT IS EQUALS VB HAS = BUT NO USE IN CASE!!!!
    👦 .... y'know what, I'll just take over from here.


  • Dupa

    Yeah, I too hate it when there are no comments.

    Otherwise, perfectly valid way of type checking in what? .NET?

    Filed under: But programming is full of strings!



  • You could try doing this in Cool, but if anyone wrote their own toString method, it wouldn't work.

    Yeah, Cool is the best language!


  • Trolleybus Mechanic

    @kt_ said:

    .NET?

    Yes, though really it's the same in any language.

    		If ReturnValue Is GetType(TextBox) Then
    
    		End If
    

    Though when I see type checking like this, it almost always could be done with OOP instead.

    What is done:

    if obj is type(something) then
       value = obj.someProp
    else if ob is type(somethingelse) then
       value = obj.someotherProp
    end if
    

    When it should just be:

    class someBase
        string someProp;
        string someotherProp
    
        string GetThisSpecificProp;
    
    class something : someBase
         string GetThisSpecificProp() { return prop; }
    
    class somethingelse : someBase
        string GetThisSpecificProp() { return someotherProp; }
    
    ...
    
    /* OMFG NOW THIS WILL JUST WORK FOR ANY OF THE OBJECTS WITHOUT IF ELSE SELECT BULLSHEEEETS */
    getvalue(someBase obj)
        return obj.GetThisSpecificProp()
    
    


  • @Lorne_Kates said:

    When it should just be:

    Until you have this pattern in two completely different areas of code (with different set of types being switched on) and you discover that you can't inherit from two bases and one of them has to use a different solution pattern. Or... you are already creating a subclass, so you can't use your own base class (for example, you're writing a control or a form).



  • That's a horrible (and remarkably common) antipattern in most cases. About the only place where you can get away with it is if you're trying pro provide a common facade to differently-implemented objects. And even that should be done with respondsTo or something similar, rather than hardcoding specific class names in place.


  • Dupa

    @Lorne_Kates said:

    it almost always could be done with OOP instead.

    But the OOPS way was chosen instead. 🕶

    BTW, I was joking.



  • Hmm... well, I guess that's one good thing about Java not supporting operator overloading... you have to use .equals on Strings and you'd hopefully notice that your editor's autocomplete has an .equalsIgnoreCase in its list...



  • This is one thing Haskell gets right, with its type classes. Classes without inheritance means there's no multiple inheritance problem.

    Inheritance is a scourge to object orientation.


  • ♿ (Parody)

    @Jaime said:

    Until you have this pattern in two completely different areas of code (with different set of types being switched on) and you discover that you can't inherit from two bases and one of them has to use a different solution pattern. Or... you are already creating a subclass, so you can't use your own base class (for example, you're writing a control or a form).

    Isn't that the point of using an interface (assuming the language has them)?


  • ♿ (Parody)

    @powerlord said:

    equalsIgnoreCase

    Ffffffffffffffffffffffffffffffffuuuuuuuuuuuuu....damnit...some of the idiots I work with use this. But only when you already know what the case is going to be, because all of the values are based on static final Strings. Mother fucker.



  • Yes. Can't you abuse object orientation in languages that don't have interfaces to emulate them? I guess you need duck typing for the naive implementation to work. Something like:

    class FooI
       def new(obj)
        self.obj = obj
    
      def method
        self.obj.method()
    
      def etc
        self.obj.etc()
    

    Functors are way nicer. So are Haskell classes.


  • ♿ (Parody)

    @Captain said:

    Can't you abuse object orientation in languages that don't have interfaces to emulate them? I guess you need duck typing for the naive implementation to work.

    Yeah, I guess duck typing would do it. I'm sure VB.NET doesn't have that. I'm not sure at all about whether or not it has interfaces. I do java during the day when I'm not trolling you guys, and I know that I have classes that are very closely related, but also have very different inheritance. I wanted to use them interchangeably for some things, so I made an interface to cover that. BAM. Piece of cake.

    The dumbshits I work with would have come up with some Rube Goldberg thing like what @Lorne_Kates posted, though. They are prone to carcinogenic copy pasta and tempt me to restart the Anti-Chinese league.



  • @boomzilla said:

    I do java during the day when I'm not trolling you guys

    So you have no experience with Java?



  • @powerlord said:

    Hmm... well, I guess that's one good thing about Java not supporting operator overloading... you have to use .equals on Strings

    Cool doesn't have that problem.



  • :vomit:


  • FoxDev

    .... Cool might not have that particular problem, but it still has the very scary words "And this will crash at runtime"

    Cool is so cool that a NPE doesn't mess about with throwing an exception or signaling an error state or any namby pamby stuff like that, no instead Cool does the equivalent of raising SIGSEGV (other wise known as "WTF, my program just crashed and printed 'Segmentation Error' to the console?!").

    that's right. Cool is so chill, it would rather crash completely than throw a fitexception!

    </🚎>



  • No, it doesn't segfault. That would be too easy to debug. Instead, it prints a message and then exits with status 0.


  • FoxDev

    i did say it did the equivalent did i not?

    okay... add "with core dumps disabled" to that description and it's slightly more accurate



  • @boomzilla said:

    I'm sure VB.NET doesn't have that. I'm not sure at all about whether or not it has interfaces.

    I understand the hate of the VB.Net syntax, but why do so many people think VB.Net is missing features? VB has everything C# has, and it had some of it long before C#, like optional method arguments - and it has some things C# still doesn't have, like a native language elements for event handling that makes binding an event handler read better and invoking one less error-prone.



  • Java could have done that, but == instead does what you think... reference equality.



  • Java is pretty much the ONLY language where string1 == string2 is testing for reference equality. Unless you count C.


  • Trolleybus Mechanic

    @boomzilla said:

    Rube Goldberg thing like what @Lorne_Kates posted, though

    I posted a rough mockup of what can be used in most of the cases I see string abuse like this.

    It almost always comes from dynamic form generation. Y'know-- user creates a survey by picking a bunch of questions and each question has a type (text, dropdown, date picker, etc). Engine turns that into a series of controls, handles the postback and saves into data. We've all written them, I'm sure.

    The render part is a huge if/else block of

    if dbtype == "textbox" 
        tb = new Textbox()
        tb.ID = "textbox_" + dbkey
        form.add(tb)
    else if dbtype == "dropdownlist"
        ddl = new DropDownList()
        ddl.ID = "dropdown_" + dbkey
        ddl.mode = dbvalues("multiselect_mode")
        form.add(ddl)
    ...
    

    And so on for every supported control type. A refactor might make that look much nicer:

    Control c
    if dbtype=="textbox"
       c = new Textbox()
    ...
    end if
    /* Put all shared properties here */
    c.ID = dbtype + dbkey
    form.add(c)
    

    The magic comes much later when trying to get the values out of the submitted form. It's when the developer's lack of OOP and Framework knowledge really shine. Here's where you can do

    Control c = form.findControl(dbtype + dbkey)
    if c is TextBox or subclassOf(Textbox)
        valueToDB = ((TextBox)c).Text
    else if c is ListControl or subclassOf(ListControl)
        valueToDB = ((ListControl)c).SelectedValue
    ...
    SaveValuesToDB(form, user, valueToDB)
    

    Because then you start getting into dumbshit of finding the control, looking for it's type as a string-- repeating the same "get value" code for controls that are subclasses of each other, and so forth.

    This could be simplified with a common interface that forces controls to implement "GetValuesForDB", for example. That way a control is responsible for returning it's value in an expected manner, and you never need to change the "user clicked submit" code ever. Just create a new class, implement the interface, done.

    InterfaceControl ic = form.find(dbtype + dbkey)
    SaveToDB(ic.GetValuesForDB, form, user)
    

    "Can we have a control that is a spinner counting from one to 10?"

    Done.



  • VB.NET has no proper null.

    Adding type safety to VB.NET is a giant pain:

    VB.NET is always used with Option Strict off and switching it on and fixing all the code would take ages.
    Oh and Option Strict disallows implicit toString() for number types :wtf:

    This is more of an ecosystem/personal preference thing, but VB.NET and type safety don't work together.

    Just from the top of my head.


  • ♿ (Parody)

    @Jaime said:

    I understand the hate of the VB.Net syntax, but why do so many people think VB.Net is missing features?

    I've never used it. I've also only minimally used even C#. Caveats like the one I used are evolved defenses against rabid pendants.



  • @aliceif said:

    VB.NET has no proper null.

    Nothing plays the role of null in VB. There certainly are differences, some good and some bad. I like that VB uses a SQL-like Is Nothing instead of C#'s == null. C# uses the legacy semantics of pretending that null is a pointer to unused memory where VB actually thought about how they wanted Nothing to work and made it work that way.

    Your definition of "proper" seems to be "works like C", in which case of course C# fits your definition better.

    @aliceif said:

    VB.NET is always used with Option Strict off and switching it on and fixing all the code would take ages.

    Only if you have bad code, that's not VB's fault.

    @aliceif said:

    Oh and Option Strict disallows implicit toString() for number types :wtf:

    Just like C#.

    @aliceif said:

    This is more of an ecosystem/personal preference thing, but VB.NET and type safety don't work together.

    Totally personal preference. Covariance, contravariance, extension methods, LINQ, generics, lambdas, anonymous functions... they all work just as well in VB as they do in C#. On the type safety end - VB has date and XML literals that C# lacks.

    It's fine to say you don't like VB, but if you say it's lacking features or "not as type safe as C#", you're going to get an argument.


  • Winner of the 2016 Presidential Election

    @ben_lubar said:

    Java is pretty much the ONLY language where string1 == string2 is testing for reference equality. Unless you count C.

    Nah, C does by-val too. E.g.:

    #include <stdio.h>
    
    int main(){
        char string1 = 'a';
        char string2 = 'a';
        printf("%d", string1 == string2);
    }
    
    <trolleybus passengers=1 />


  • char[] is roughly equivalent to string, not char.



  • @accalia said:

    okay... add "with core dumps disabled" to that description and it's slightly more accurate
    Also add "crashes with a success code". Because that's even more of a WTF.@aliceif said:
    VB.NET has no proper null.
    Nothing@aliceif said:
    Adding type safety to VB.NET is a giant pain: VB.NET is always used with Option Strict off and switching it on and fixing all the code would take ages.
    Option Strict is on by default in projects that started out in .NET. @aliceif said:
    Oh and Option Strict disallows implicit toString() for number types :wtf:
    Isn't it a good thing we've got String.Format and all the formatting overloads to every output function in the history of ever?@aliceif said:
    This is more of an ecosystem/personal preference thing, but VB.NET and type safety don't work together.
    You've said this twice now. You still have nothing backing your assertion aside from a Classic VB compatibility hack that's off by default. Care to try again?
    ... :hanzo: by Jaime. Still...



  • @TwelveBaud said:

    Option Strict is

    Set for new projects based on the VS setting:

    And if I'm going to trust MSDN, it does default to Off.



  • Damn, you're right. I just remember VB.NET 2002 putting "Option Strict On" at the top of each and every one of my source files, which I left there because I had no idea at the time what the hell it did. Didn't seem to affect me in the slightest.



  • Who cares? It's easy to turn on and only reflects badly on the developer that leaves it off, not the language.

    Line numbers are off by default in the code editor for all languages. In my opinion, any developer that doesn't turn them on is an idiot.


  • Java Dev

    That still exits nonzero by default.

    It acts equivalently to an oracle helper binary that failed.


  • FoxDev

    @PleegWat said:

    It acts equivalently to an oracle helper binary that failed.

    you mean it pisses off into hyperspace never to be seen nor heard from again?



  • Hah! You guys are morons!
    Nothing in VB does not behave like null in C#.

    For non-nullable value types, Nothing in Visual Basic differs from null in C#. In Visual Basic, if you set a variable of a non-nullable value type to Nothing,
     the variable is set to the default value for its declared type. In C#, 
    if you assign a variable of a non-nullable value type to null, a compile-time error occurs.
    


  • @Jaime said:

    Just like C#.

    Have you ever used c#?

    string s = "In the year " + DateTime.Today.Year + ", Jaime was wrong!";
    Console.WriteLine(s);
    

    Compiles and outputs "In the year 2015, Jaime was wrong!".



  • @Jaime said:

    Only if you have bad code, that's not VB's fault.

    It is. It encourages bad behaviour by default.

    If you want people to do things correctly, encourage them to do so. Don't hide type safety behind a compiler setting.



  • @aliceif said:

    It is. It encourages bad behaviour by default.

    If you want people to do things correctly, encourage them to do so. Don't hide type safety behind a compiler setting.

    QFT. Until you have had to wade through the turd that is an existing VB.NET code base, most people just don't understand how bad shit can get. I tried to turn Option Strict on with a .Net 3.5 "native" application. 300+ errors immediately. All involving type casting mismatches because VB developers hate type systems. Or hate having to not make turd code, not entirely sure.



  • @aliceif said:

    string s = "In the year " + DateTime.Today.Year + ", Jaime was wrong!";
    Console.WriteLine(s);

    Compiles and outputs "In the year 2015, Jaime was wrong!".

    Ugh, and you consider this a good thing? I tend to be wary of languages which think that adding up numbers and strings somehow makes sense.



  • @ixvedeusi said:

    Ugh, and you consider this a good thing? I tend to be wary of languages which think that adding up numbers and strings somehow makes sense.

    QFT. Implicit conversions between unrelated types (strings and any other type, for instance) go against type safety. You should use string s = String.Format("In the year {0} (and every other year), formatted strings are the best!", DateTime.Today.Year);


  • Trolleybus Mechanic

    @aliceif said:

    Compiles and outputs "In the year 2015, Jaime was wrong!".

    // adds Google Calendar appointment to come back here on January 1st, 2016, and make "ur wrong" joke.


  • FoxDev

    @Lorne_Kates said:

    @aliceif said:
    Compiles and outputs "In the year 2015, Jaime was wrong!".

    // adds Google Calendar appointment to come back here on January 1st, 2016, and make "ur wrong" joke.

    why wait? just fiddle with your system clock and run it today.



  • @aliceif said:

    Hah! You guys are morons!Nothing in VB does not behave like null in C#.

    Oh noes! It behaves like default(T)! Which for reference types -- everything but the numbers and structs -- is null! Jesus Christ, if you have to resort to technicality pedantry...



  • @Lorne_Kates said:

    Though when I see type checking like this, it almost always could be done with OOP instead.

    This is kinda true, except with UI frameworks in .NET where virtual methods are optional, and library developers are compelled to make life difficult by using things like sealed classes, or making all the useful methods internal. Sure you can use reflection to get around this, but it's annoying and somehow feels wrong.

    So you'd end up with

    public class TextboxThatDoesSpecifficShit : TextBox, IDoesSpecifficShit
    {
       public void IDoesSpecifficShit.DoSpecifficShit()
       {
        ...
       }
    }
    

    Which is fine, except it'll make using the UI designer a pain in the arse, cause somehow every version of VS after 2005 has made it so that using controls which subclass system controls crash the UI designer in new and different ways, requiring weird incantations of rebuild-all, followed by closing and opening the designer window to make it work again.

    In .NET, extension methods can be helpful, in that you get nice OO syntax in the code which uses it, but it's still a mess of is checks somewhere in your codebase. But at least it's reusable.

    IMHO instanceof in java or is in .NET work just fine. and if you're working with UI controls, it's not super important to have a perfectly clean object model.

    But in general. Yeah, you're right. OO principles are better, cleaner, require less code, and generally establish a good pattern for further extension.


  • Discourse touched me in a no-no place

    @TwelveBaud said:

    if you have to resort to technicality pedantry

    ...you might not be new here?



  • @TwelveBaud said:

    technicality pedantry

    The best kind of pedantry!


Log in to reply