2
\$\begingroup\$

I have two different data inputs for the same value, I want to use the non empty one if one of them is, to return the empty string if both are empty, and to flag an error if both are not empty but differ and return one of them.

Empty for my criteria matches the meaning of string.IsNullOrEmpty().

And it's okay that it's written as a property (don't worry about that part.)

This works but feels overly verbose. Can you think of any alternatives?

    public string Callkey
    {
        get
        {
            if (string.IsNullOrEmpty(AS_CALL_KEY) && !string.IsNullOrEmpty(CALLKEY)) 
            {
                return CALLKEY.Trim();
            }
            if (!string.IsNullOrEmpty(AS_CALL_KEY) && string.IsNullOrEmpty(CALLKEY))
            {
                return AS_CALL_KEY.Trim();
            }
            if (!string.IsNullOrEmpty(AS_CALL_KEY) && !string.IsNullOrEmpty(CALLKEY))
            {
                if (!AS_CALL_KEY.Trim().Equals(CALLKEY.Trim()))
                {
                    _error = true;
                }
                return AS_CALL_KEY.Trim();
            }
            if (string.IsNullOrEmpty(AS_CALL_KEY) && string.IsNullOrEmpty(CALLKEY))
            {
                return "";
            }
            _error = true;
            return "THISNEVERHAPPENS";
        }
    }
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

You have four cases and each of them behaves differently, so you actually need to have four different branches. But you can simplify your code by extracting the checks into variables and using nested ifs:

public string CallKey
{
    get
    {
        bool callKeyEmpty = string.IsNullOrEmpty(CALLKEY);
        bool asCallKeyEmpty = string.IsNullOrEmpty(AS_CALL_KEY);

        if (callKeyEmpty) 
        {
            if (asCallKeyEmpty)
                return "";
            else
                return AS_CALL_KEY.Trim();
        }
        else
        {
            if (asCallKeyEmpty)
                return CALLKEY.Trim();
            else
            {
                if (AS_CALL_KEY.Trim() != CALLKEY.Trim())
                    _error = true;
                return AS_CALL_KEY.Trim();
            }
        }
    }
}

As an added benefit, you can now remove the “this never happens” part.

\$\endgroup\$
3
\$\begingroup\$

I would check the error condition separately, then return the value you want using the "null-coalesce" operator and some clever extensions:

public string CallKey
{
    get
    {
        //extension methods below
        var callKey = CALLKEY.NullIfBlank().SafeTrim();
        var asCallKey = AS_CALL_KEY.NullIfBlank().SafeTrim();

        //you can make this an if statement if you don't want it resetting _error
        _error = callKey != null && asCallKey != null && callKey != asCallKey;

        return asCallKey ?? callKey ?? String.Empty;        
    }
}

...

//the NullIfBlank() extension method; useful to have around
public static string NullIfBlank(this string input)
{
   if (String.IsNullOrWhiteSpace(input)) return null;
   return input;
}

//and the SafeTrim() method, again useful
public static string SafeTrim(this string input)
{
   return input == null ? input : input.Trim();
}
\$\endgroup\$
3
  • \$\begingroup\$ This is very neat. \$\endgroup\$
    – Leonid
    Commented Jul 18, 2012 at 16:09
  • \$\begingroup\$ Since you are using NullIfBlank and SafeTrim together, it might make sense to have the NullIfBlank procedure take a bool trim flag. \$\endgroup\$
    – Leonid
    Commented Jul 18, 2012 at 23:26
  • \$\begingroup\$ That could work if this is the only usage, but conceptually those are two different operations which might have value separately elsewhere in the system, so I separated them. \$\endgroup\$
    – KeithS
    Commented Jul 19, 2012 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.