• (cs)

    Please modify this code to include a cover sheet on all TPS reports before they go out.  Didn't you get that memo?

  • Lenny (unregistered)

    Do the chickens have large talons?

  • Alex (unregistered)

    They should have left the method block empty, which would take care of those pesky runtime exceptions as well.

    Look ma - no errors!

  • (cs) in reply to loneprogrammer

    Does virtual in C# mean the same as it does in C++?
    I am pretty sure that virtual does not mean "not real."

  • diaphanein (unregistered) in reply to Alex

    I'll admit to having done similar things in ASP.Net.  This is primarily a workaround a limitation in the designer.  Basically, if your page inherits from an abstract class, the designer cannot instantiate your page, and hence no design-time support.  So, I had to do this in that situation.  I didn't go with an interface because there were methods in the class that actually had usable methods.

  • smalltalker (unregistered)

    Looks like a smalltalk developer that hasn't quite learned the local patois. As my father likes to say, "I can write fortran in any language'.

  • purplie (unregistered)

    I've also done this when the base class contains some common code that subclasses are supposed to include using super().


  • Jason (unregistered)

    Handle the exception and at least you have a freshly initialized MemoryStream

  • Lennox (unregistered) in reply to purplie

    I work with the developer in question.  In the original code for this class, there are only 2 methods, neither of with do anything (well, virtually speaking of course).  Also, this class isn't a base class for anything that would be used in the designer.

    The real kicker is the *** DO NOT USE!! (VIRTUAL METHOD) ***  comment.  And if for some reason you did decide to use the function, not only does it throw a special exception created just for calling virtual methods, but it also creates a new memory stream.... just in case you need it.  WTF?!?

    <FONT color=#000000></FONT>

  • (cs) in reply to Lennox
    Anonymous:

    The real kicker is the *** DO NOT USE!! (VIRTUAL METHOD) ***  comment.  And if for some reason you did decide to use the function, not only does it throw a special exception created just for calling virtual methods, but it also creates a new memory stream.... just in case you need it.  WTF?!?

    <font color="#000000"></font>



    The new memory stream is there for you to barf into... yeah...
  • Jacob (unregistered) in reply to diaphanein

    For this situation, you can use Conditional Directives so that you can at least get some useful compile time info when compiling in release mode:

    #If DEBUG Then

    Public Class MyTempClass

    #Else

    Public MustInherit Class MyTempClass

    #End If

     

    End Class

     

    Use the same constructs for your methods.

  • tekiegreg (unregistered)

    I was guilty of doing something like that once, at first I had an abstract class with several built in methods.  But after awile as my coding progressed,  I kept overriding everything in my child classes, one day I looked and said "I have nothing more than an interface now." and swapped out approriately.  It can happen as coding evolves.

  • Marty (unregistered)

    Hmm, never seen that 'out' parameter modifier before.   After doing some research on it, what the heck is the difference between 'out' and 'ref'?

  • phanto (unregistered) in reply to Marty

    out is an output only parameter, the compiler complains if you read from such a variable before you set it inside the method.

    ref is basically an in out parameter compareable with pass by reference in c++

  • Special (unregistered) in reply to Marty

    Anonymous:
    Hmm, never seen that 'out' parameter modifier before.   After doing some research on it, what the heck is the difference between 'out' and 'ref'?

    You can pass an uninitialized variable to an out param. Try it with a ref param and you'll get a compile time error

  • (cs) in reply to Lenny
    Anonymous:
    Do the chickens have large talons?


    Actually, in this case they are virtual chickens.  Virtually sacrificed. 
  • (cs)

    so you're not supposed to use this method, because it doesn't generate the cover sheet right?

    WTF does PC Load Letter mean??

  • (cs)
    Alex Papadimoulis:

        string ai_sProjectNumber,
        out System.IO.MemoryStream ao_oTpsMemoryStream
        TpsReportGeneratorException v_oException = new TpsReportGeneratorException(
        ao_oTpsMemoryStream = new MemoryStream();

    Those prefixes had better not mean what I think they mean.

    ao_oTpsMemorySteam = Asinine Output Object?

    v_oException = Virtual Object Exception?

  • (cs)

    I don't quite get this one. Should the method just be empty and have MustOverride keyword (or the C++ equiv) before the function definition?

  • -L (unregistered) in reply to Special
    Anonymous:

    Anonymous:
    Hmm, never seen that 'out' parameter modifier before.   After doing some research on it, what the heck is the difference between 'out' and 'ref'?

    You can pass an uninitialized variable to an out param. Try it with a ref param and you'll get a compile time error


    Right. I do not know C#, but what is the rationale for being able to pass uninitialized variables to out parameter? That sounds like a major WTF to me...

    And speaking of that, why on earth have distinct "ref " and "in out" formal parameters? Shouldn't this decision be left to the compiler, or be stated in more explicit form (like passing a "pointer" instead of "ref")?

    This is just off the top of my head, I don't know C#, but these things just seem strange.
  • djc (unregistered) in reply to -L

    Another WTF:

    And speaking of that, why on earth have distinct "ref " and "in out" formal parameters? Shouldn't this decision be left to the compiler, or be stated in more explicit form (like passing a "pointer" instead of "ref")?

    A pointer is not more explicit than ref, out, etc. When you use a pointer no one knows if the var is in, out, or in out. They just have to guess!

  • Matt (unregistered) in reply to diaphanein
    Anonymous:

    I'll admit to having done similar things in ASP.Net.  This is primarily a workaround a limitation in the designer.  Basically, if your page inherits from an abstract class, the designer cannot instantiate your page, and hence no design-time support.  So, I had to do this in that situation.  I didn't go with an interface because there were methods in the class that actually had usable methods.



    I had to do the same thing.  :(
  • David (unregistered)

    I'm sorry but I have to play dumb and say, first of all, WTF language is this in???

  • Ponto (unregistered)

    I've done something similar, and I still do not know how to do it better. I have a tree which consists of nodes of several types. Class Node is the baseclass of all node types and is responsible for the tree structure (parent, first_child, next_sibling pointers). Other nodetypes have different sets of methods.

    When I traverse the tree the logic of the application gives me knowledge of the node types without asking the objects themselves. Using this information I want to call methods of the derived type without using evil casts.

    The solution was to create virtual methods for nearly each needed method in the Node class and let them throw an exception when they are called. Making them abstract is not a solution because then they have to be implemented in each derived class.

    However, if anyone knows a better solution, let me know.

  • Welcome To The Machine (unregistered)

    <FONT face=Tahoma>Looks like this guy didn't get the memo on the new cover sheet for TPS reports. Can someone forward him a copy? [8-|]</FONT>

  • Frederik (unregistered) in reply to -L

    Anonymous:

    Right. I do not know C#, but what is the rationale for being able to pass uninitialized variables to out parameter? That sounds like a major WTF to me...

    And speaking of that, why on earth have distinct "ref " and "in out" formal parameters? Shouldn't this decision be left to the compiler, or be stated in more explicit form (like passing a "pointer" instead of "ref")?

    Consider this:

    string fullName = "Bill Gates";
    string firstName;
    string lastName;
    ParseName(fullName, out firstName, out lastName);

    There is no reason for you to initialize firstName and lastName. If you don't pass the parameter as an out parameter, C# will complain. The method is supposed to initialize the parameters.

    As opposed to:

    int string x = "First";
    int string y = "Second";
    SwitchValues(ref x, ref y);

    where you clearly want initialized variables before the method is being called.

    Hope it helps

  • -L (unregistered) in reply to Frederik
    Anonymous:

    Anonymous:

    Right. I do not know C#, but what is the rationale for being able to pass uninitialized variables to out parameter? That sounds like a major WTF to me...

    There is no reason for you to initialize firstName and lastName. If you don't pass the parameter as an out parameter, C# will complain. The method is supposed to initialize the parameters.

    (snip)

    Hope it helps



    Ah, my bad. For some reason I had my thinking reversed, thinking that the method could pass uninitialized parameter values through out parameter, which is not what the original author said at all.

    The out behaviour Frederik describes is perfectly sensible.
  • R. Stiller (unregistered) in reply to loneprogrammer
    loneprogrammer:
    Does virtual in C# mean the same as it does in C++?
    I am pretty sure that virtual does not mean "not real."
    Virtual means i C# that the member function can be overridden. C++ virtuals in C# are abstract member functions. To override a method in C# you must mark your method as "override".
  • Simon Farnsworth (unregistered) in reply to Ponto
    Anonymous:
    I've done something similar, and I still do not know how to do it better. I have a tree which consists of nodes of several types. Class Node is the baseclass of all node types and is responsible for the tree structure (parent, first_child, next_sibling pointers). Other nodetypes have different sets of methods.
    When I traverse the tree the logic of the application gives me knowledge of the node types without asking the objects themselves. Using this information I want to call methods of the derived type without using evil casts.
    The solution was to create virtual methods for nearly each needed method in the Node class and let them throw an exception when they are called. Making them abstract is not a solution because then they have to be implemented in each derived class.

    However, if anyone knows a better solution, let me know.



    Making them abstract is exactly the solution you should be using. Ask yourself this: why is throwing an exception in buggy code better than refusing to compile it?
    Alternatively, look at the Visitor Design Pattern for ideas on how to get the behaviour you want.

  • (cs) in reply to Matt

    <font size="1">

    Anonymous:
    Anonymous:
    </font>

    <font size="1">I'll admit to having done similar things in ASP.Net.  This is primarily a workaround a limitation in the designer.  Basically, if your page inherits from an abstract class, the designer cannot instantiate your page, and hence no design-time support.  So, I had to do this in that situation.  I didn't go with an interface because there were methods in the class that actually had usable methods.</font>

    <font size="1">


    I had to do the same thing.  :(


    Conditional compilation is your friend.

    In C# you can use:

        // the webform designer needs to instantiate the page base classes, and doesn't work
        // when the base class is abstract. use a concrete class for dev, but switch to abstract for release.
    #if DEBUG
        public class PageBase
    #else
        public abstract class </font><font size="1">PageBase</font>
    <font size="1">#endif
    {/* class definition */}

    I believe someone posted the VB equivalent further up.
    </font>

  • (cs)

    All that typing to make a runtime version of the abstract keyword (or interfaces). What a pity. At least it creates a new MemoryStream for you though. I like the implications of the "DO NOT USE!! (VIRTUAL METHOD)" comment. That is, thankfully, the classes that derive from BaseTpsReportGenerator and implement GenerateTpsReport aren't really virtual, so they're okay to call. :)

    The guy is using reflection though (GetType()), so it looks like someone who knows enough to really make a mess of things.

  • foo (unregistered) in reply to Simon Farnsworth

    >why is throwing an exception in buggy code better than refusing to compile it?

    better ?

    refusing to compile it means you can't go on to other things and let this sleeping

    the exception sits there as a reminder for the poor developper when his apps go through it

  • Ponto (unregistered) in reply to Simon Farnsworth
    Anonymous:
    ...
    Making them abstract is exactly the solution you should be using. Ask yourself this: why is throwing an exception in buggy code better than refusing to compile it?
    Alternatively, look at the Visitor Design Pattern for ideas on how to get the behaviour you want.

    If I make the methods abstract in the Node class and if I implement all this methods in all derived classes (which is unnecessary for most of them), then I will not get more compiler errors than I get now.

    The compiler does not forbid calling abstract functions.

    The compiler forces me to implement method in derived classes which are meaningless for most of them. The only thing such meaningless methods can do is throwing an exception. The same thing which is now done centralized at the base class. I do not see why the code is buggy?

  • Hank Miller (unregistered) in reply to Ponto
    Anonymous:
    I've done something similar, and I still do not know how to do it better. I have a tree which consists of nodes of several types. Class Node is the baseclass of all node types and is responsible for the tree structure (parent, first_child, next_sibling pointers). Other nodetypes have different sets of methods.
    When I traverse the tree the logic of the application gives me knowledge of the node types without asking the objects themselves. Using this information I want to call methods of the derived type without using evil casts.
    The solution was to create virtual methods for nearly each needed method in the Node class and let them throw an exception when they are called. Making them abstract is not a solution because then they have to be implemented in each derived class.

    However, if anyone knows a better solution, let me know.



    in C++ there is dynamic_cast and static_cast for these situations.


    Though someone else already mentioned the visitor pattern, which looks like an even better solution.  (I had not encountered them before, and thus forgot about them from my GoF book)

    Which to use I suppose depends on how often you need it.  If you are only encounter this situation a couple times it might not be worth all the code to create visitors, while if you have many situations where you want to do something to something else that the base class shouldn't support you use a visitor.

  • Carl (unregistered)

    This is pretty funny.  I really like the design time warning: " DO NOT USE!! (VIRTUAL METHOD) " and the run-time warning: an exception being thrown.  Unfortunately it doesn't throw a compile time warning.  Chances are, whoever has to work with this piece of crap will go diving down through the code and find this method and see that it's not supposed to be used.  Why throw an exception as well?  Like there's some guy out there who can't figure out why his call to this method isn't doing anything.  The other design nugget that's interesting is that this person can't just throw an exception and be done with it, they designed their method with an out parameter that requires it to be initialized in the method.  So instead of just being able to throw an exception they had to initialize the variable in order to get it to compile.  Oops.  Probably should've spent more time at the drawing board and less time at the keyboard.

  • Ponto (unregistered) in reply to Hank Miller
    Anonymous:


    in C++ there is dynamic_cast and static_cast for these situations.

    Though someone else already mentioned the visitor pattern, which looks like an even better solution.  (I had not encountered them before, and thus forgot about them from my GoF book)

    Which to use I suppose depends on how often you need it.  If you are only encounter this situation a couple times it might not be worth all the code to create visitors, while if you have many situations where you want to do something to something else that the base class shouldn't support you use a visitor.

    As I already said, I do not want to use casts. With casts the solution is really simple. Using the visitor pattern it might work, but there is a lot of overhead - especially in code. Additionally the visitor pattern is more appropriate for extra functionality of the elements and not for the first class functionality.

    Right now I think that when you do not want to use casts and want each subclass only implement a subset of all methods throwing an exception when it is called for the base class is the best way.

  • Simon Farnsworth (unregistered) in reply to Ponto

    Why don't you want to use casts? dynamic_cast<> will get you the same behaviour you've got already, as it throws an exception if the cast is not possible, while if static_cast<> is possible, it'll check at compile time that you're doing what you think you're doing.

    I think your code qualifies as a potential WTF, simply because it's not clear to a maintenance programmer that the method will sometimes work, and sometimes not. A C++ programmer should be aware that dynamic_cast<> can throw a bad_cast exception, and will thus see what the code's up to; it's not so clear that calling a virtual function can throw what's effectively a bad_cast exception. Further, the overhead of RTTI shouldn't be significant compared to virtual functions; it should be a simple tag comparison in a decent compiler.

    Finally, I wasn't suggesting that you use the Visitor pattern as-is; I was suggesting that you use the concepts of the visitor pattern to create something without the base-class exception that still functions.

  • (cs)

    "DO NOT PRESS"  Whoops... "The Earth will self destruct in 30 seconds... 29... 28..."  WHY would you put do not use? and Then throw and error if it IS used?

  • (cs) in reply to cm5400
    cm5400:

    "DO NOT PRESS"  Whoops... "The Earth will self destruct in 30 seconds... 29... 28..."  WHY would you put do not use? and Then throw and error if it IS used?



    As the user repeatedly and rapidly presses cancel: "Pressing cancel won't change anything ... 27 ... The big red button was plainly labeled ... 26 ... and you pushed the button anyway. Enjoy your imminent ... 25 ... destruction, bozo. "

    I can imagine the exception gives some sort of error message "Develper, you've called a method that you were instructed not to call. Don't do that. It was plainly labeled, but you called it anyway."
  • JohnO (unregistered) in reply to Ponto

    As I already said, I do not want to use casts.

    You said that the tree structure already tells you what kind of node you have.  If that's true, then why is casting "evil?"  The two situations seem exactly the same to me in terms of how the program works except that in one case you are introducing a WTF and in the other you are using the language as intended and as 99% of competent developers would expect you to.

    In your scenario, you are querying the node to determine what methods to call.  If you make a mistake, then you call the base class implementation and get a run-time exception.  In what I would consider the "standard" solution, you would query the node to determine what type to cast it to, cast it and invoke the method.  If you make a mistake you get a cast exception.  What's the benefit of what you are doing over the "standard" way?

  • (cs)

    OMG, if you are gonna ignore all the OO features of Java why bother with Java at all!

    If a student handed code like that up to me I'd fail them, imagine finding it in a real app!

    BTW, it is not possible to reply to posts on this board using Camino on OS X. Made me go WTF! mutters about the KISS principle

  • (cs) in reply to voyager
    voyager:
    BTW, it is not possible to reply to posts on this board using Camino on OS X. Made me go WTF! *mutters about the KISS principle*

    It just wouldn't be thedailywtf without the wtf forum software. C'mon, admit it.
  • enska (unregistered) in reply to djc
    Anonymous:
    Another WTF:

    A pointer is not more explicit than ref, out, etc. When you use a pointer no one knows if the var is in, out, or in out. They just have to guess!



    const pointer.

    btw, this forum's buggy. almost a WTF in itself.

  • Marco (unregistered) in reply to Ponto
    Anonymous:

    The compiler forces me to implement method in derived classes which are meaningless for most of them. The only thing such meaningless methods can do is throwing an exception. The same thing which is now done centralized at the base class. I do not see why the code is buggy?


    If methods are meaningless for the derived classes, then you probably didn't get your classes defined in the right way: move the "meaningless" methods to the derived classes where they belong and you expect actually to implement them.

    If a method is "meaningful" for more than one subclass, consider creating an intermediate base class that includes that method and from which you derive.

    Just my 2 cents.
  • Ponto (unregistered) in reply to JohnO
    Anonymous:

    As I already said, I do not want to use casts.

    You said that the tree structure already tells you what kind of node you have.  If that's true, then why is casting "evil?"  The two situations seem exactly the same to me in terms of how the program works except that in one case you are introducing a WTF and in the other you are using the language as intended and as 99% of competent developers would expect you to.

    In your scenario, you are querying the node to determine what methods to call.  If you make a mistake, then you call the base class implementation and get a run-time exception.  In what I would consider the "standard" solution, you would query the node to determine what type to cast it to, cast it and invoke the method.  If you make a mistake you get a cast exception.  What's the benefit of what you are doing over the "standard" way?

    Maybe I am not doing the best thing in this situation, but there are experts who do similar things. For example Scott Meyers suggests in his "Effective C++ Third Edition" Item 27 (Minimize casting) that one solution to avoid dynamic_cast is moving such a function to the base class and leaving it empty.

    The difference is, that I throw an exception when it is called for a base class. However maybe leaving it empty is the better approach.

    For C++ a cast might be more WTF than such a construct.

  • Ponto (unregistered) in reply to Marco
    Anonymous:
    Anonymous:

    The compiler forces me to implement method in derived classes which are meaningless for most of them. The only thing such meaningless methods can do is throwing an exception. The same thing which is now done centralized at the base class. I do not see why the code is buggy?


    If methods are meaningless for the derived classes, then you probably didn't get your classes defined in the right way: move the "meaningless" methods to the derived classes where they belong and you expect actually to implement them.

    If a method is "meaningful" for more than one subclass, consider creating an intermediate base class that includes that method and from which you derive.

    Just my 2 cents.

    Currently I do not have meaningless functions in the derived classes. However, when I make them abstract in the base class, I have to implement them in the derived classes.

  • JohnO (unregistered) in reply to Ponto

    Responding a little late here -- hope you get to read this.  I am in the C pound world and can't remember the specifics of C increment, but in C#, you would just have an abstract class with virtual empty methods.  The subclass has the option of overriding but doesn't have to.  I am guessing that C++ doesn't have this?  If not, then if you take throwing the exception out of the base class implementation, then it does sound reasonable.

  • bp (unregistered) in reply to loneprogrammer
    loneprogrammer:
    Please modify this code to include a cover sheet on all TPS reports before they go out.  Didn't you get that memo?


    Hey man, I still have my stapler!

Leave a comment on “Virtually Unusable”

Log In or post as a guest

Replying to comment #:

« Return to Article