I'm not going to lie: there are things at work that I'm a little too picky about. This is not one of them. Herein lies a crime against all reason. Names have been changed (or just omitted) to protect the innocent, and the guilty have long since escaped into the wild. Beware, they are armed and dangerous!

The free man will observe:

public static List<string> GetMemberValues(object obj)
{
    if (obj == null)
    {
        return null;
    }
    
    // Attend well the final call of this chain!
    return obj
        .GetType()
        .GetProperties()
        .Where(n => n.Name.StartsWith("MemberNameHere"))
        .Select(x => x.GetValue(obj))
        .Where(x => x != null)
        .Select(x => x.ToString())
        .ToList();
}

The above is not a minimal reproduction; I have lifted this directly from a production codebase. My only changes are related to formatting and proprietary information (the original function referenced a specific member name). This function accepts a single object as its parameter and returns the values of any properties whose names begin with "MemberNameHere" as part of List<string>.

Now, the free man (wait, seriously, do you guys get that this is a Half-Life 2 reference? That game seems practically pre-Internet these days) will attend the call sites for this code. There are two:

// Call site A:
... = Helper.GetMemberValues(obj).ToList();

// Call site B:
... = Helper.GetMemberValues(obj).ToList();

Again, I haven't made any significant changes to this code. The left hand side of the assignment has been omitted, and the actual name of the parameter being passed has been concealed. Attend well the final call! (Ok, enough antiquated Half-Life references.) The guy who wrote those calls is the same guy who wrote the original helper method.

via GIPHY

I'm not surprised. This is the same guy who wrote the following gem:

// This one is a minimal repro. You're welcome.
static Stream WasteMemAndCpuForEveryone(Stream stream)
{
    var streamA = new MemoryStream();

    using (var streamB = new MemoryStream())
    {
        stream.CopyTo(streamB);
        streamB.Seek(0, SeekOrigin.Begin);
        streamB.CopyTo(streamA);
    }

    streamA.Seek(0, SeekOrigin.Begin);
    return streamA;
}

Still, what gets me is that we're doing something stupid here, and we're doing it badly.

The original author had a legitimate problem: he has one of two types that he needs data from, but he can't know which one he's working with. They present an identical interface to the consumer, but they don't actually have an interface for it in the IIAmAnInterface sense of the word. The GetMemberValues war crime was his way of getting around that.

...You know, without writing an interface.

Thank God for small WTF moments like this: they give us a little chance to relax and smile. Think about that, dear reader, before you come at me with a hatchet for whatever terrible WTF code I wrote today. :)