Select with no arguments

Issue #12 wontfix
Kory Taborn
created an issue

I use this library to return some pretty volatile objects, and use the Select statement often. It would be nice to be able to callSelect() and have it return the object, rather than having to specify Select(o => o) just to return a string, or some other oft used reference.

public Maybe<T> Select()
{
  return _hasValue ? _value : Maybe<T>.Not;
}

Comments (11)

  1. Kory Taborn reporter

    Correct, it does return the same value. However, I think the parameterless version would be a clearer and more expressive way to accomplish the same thing. I don't mind the normal usage, I just find writing a lambda expression to unwrap the value a bit redundant for basic data types. Additionally, some developers may not be used to anonymous methods and closures, and having a more familiar way to call the method, might make them feel more comfortable using it.

    It's just a suggestion. I marked it as an enhancement, but it's probably more accurate to consider it an aesthetic recommendation.

  2. James Jensen repo owner

    I still don't understand the purpose. Could you provide a code sample to show under what circumstances you would call the select method in this way?

  3. James Jensen repo owner

    @Kory Taborn I haven't heard anything from you in almost a year now. Can you provide a sample to show why you'd want this method, or shall I close the enhancement request?

    In general, .Select(o => o) is a code smell, since it doesn't have any functional effect. Resharper will typically detect this pattern and recommend you remove the unnecessary code.

  4. Kory Taborn reporter
    public class Thing
    {
        public Maybe<long> MaybeANumber { get; set; }
        public Maybe<string> MaybeAString { get; set; }
    }
    
    var someThings = GetThingsFromSomeService();
    
    // use some default when there is NOT a value
    var someNumbers = someThings.Select(t => t.MaybeANumber.Select().Else(0));
    var someStrings = someStrings.Select(t => t.MaybeAString.Select().Else(string.Empty));
    

    Rather than,

    public class Thing
    {
        public Maybe<long> MaybeANumber { get; set; }
        public Maybe<string> MaybeAString { get; set; }
    }
    
    var someThings = GetThingsFromSomeService();
    
    // use some default when there is NOT a value
    var someNumbers = someThings.Select(t => t.MaybeANumber.Select(n => n).Else(0));
    var someStrings = someStrings.Select(t => t.MaybeAString.Select(s => s).Else(string.Empty));
    
  5. James Jensen repo owner

    @Kory Taborn
    Why not just omit that inner Select entirely?

    // use some default when there is NOT a value
    var someNumbers = someThings.Select(t => t.MaybeANumber.Else(0));
    var someStrings = someStrings.Select(t => t.MaybeAString.Else(string.Empty));
    
  6. Kory Taborn reporter

    Is that syntax possible with Maybe? Unfortunately, I'm in a new codebase now, and haven't been able to migrate this concept in, so it's been a while since I've used the library. It could be that I just didn't realize you could unwrap the inner value without Select, but I thought there were many cases before where I had to use the Select to retrieve the inner value, and I always felt uneasy about it.

  7. James Jensen repo owner

    @Kory Taborn Yeah, much the same way LINQ allows you to execute a Sum() on any IEnumerable<> without using Select() first, Else() is available directly off a Maybe<> object, as shown in the Readme:

    // `Else` will return the given value if the `Maybe` has no value.
    bool isLucky3 = HowLuckyIs(number).Else("").Contains("lucky");
    
  8. Log in to comment