Is there a name for this anti-pattern/code smell?

前端 未结 13 2457
轻奢々
轻奢々 2021-02-12 16:00

Let me start by saying that I do not advocate this approach, but I saw it recently and I was wondering if there was a name for it I could use to point the guilty party to. So h

相关标签:
13条回答
  • 2021-02-12 16:09

    Konrad is right, C# uses dual return values all the time. But I kind of like the TryParse, Dictionary.TryGetValue, etc. methods in C#.

    int value;
    if (int.TryParse("123", out value)) {
        // use value
    }
    

    instead of

    int? value = int.TryParse("123");
    if (value != null) {
        // use value
    }
    

    ...mostly because the Nullable pattern does not scale to non-Value return types (i.e., class instances). This wouldn't work with Dictionary.TryGetValue(). And TryGetValue is both nicer than a KeyNotFoundException (no "first chance exceptions" constantly in the debugger, arguably more efficient), nicer than Java's practice of get() returning null (what if null values are expected), and more efficient than having to call ContainsKey() first.

    But this is still a little bit screwy -- since this looks like C#, then it should be using an out parameter. All efficiency gains are probably lost by instantiating the class.

    (Could be Java except for the "string" type being in lowercase. In Java of course you have to use a class to emulate dual return values.)

    0 讨论(0)
  • 2021-02-12 16:11

    In defense of the anti-pattern designation, this code lends itself to being used in a few ways:

    1. Object x = MyFunction().payload; (ignoring the return result - very bad)
    2. int code = MyFunction().result; (throwing away the payload - may be okay if that's the intended use.)
    3. FunctionResult x = MyFunction(); //... (a bunch of extra FunctionResult objects and extra code to check them all over the place)

    If you need to use return codes, that's fine. But then use return codes. Don't try to pack an extra payload in with it. That's what ref and out parameters (C#) are for. Nullable types might be an exception, but only because there's extra sugar baked in the language to support it.

    If you still disagree with this assessment, DOWNVOTE this answer (not the whole question). If you do think it's an anti-pattern, then UPVOTE it. We'll use this answer to see what the community thinks.

    0 讨论(0)
  • 2021-02-12 16:13

    This approach is actually much better than some others that I have seen. Some functions in C, for example, when they encounter an error they return and seem to succeed. The only way to tell that they failed is to call a function that will get the latest error.

    I spent hours trying to debug semaphore code on my MacBook before I finally found out that sem_init doesn't work on OSX! It compiled without error and ran without causing any errors - yet the semaphore didn't work and I couldn't figure out why. I pity the people that port an application that uses POSIX semaphores to OSX and must deal with resource contention issues that have already been debugged.

    0 讨论(0)
  • 2021-02-12 16:15

    It is called "Replace Error Code with Exception"

    0 讨论(0)
  • 2021-02-12 16:15

    If you expect your method to fail occasionally, but don't consider that exceptional, I prefer this pattern as used in the .NET Framework:

    bool TryMyFunction(out FunctionResult result){    
    
         //...    
         result = new FunctionResult();
    }
    
    0 讨论(0)
  • 2021-02-12 16:17

    I am not sure this is an anti-pattern. I have commonly seen this used instead of exceptions for performance reasons, or perhaps to make the fact that the method can fail more explicit. To me, it seems to be a personal preference rather than an anti-pattern.

    0 讨论(0)
提交回复
热议问题