I would do this a little differently...
/// <summary>
/// Uses <see cref="EqualityComparer{TValue}"/> to determine if <paramref name="left"/> is
/// equal to <paramref name="right"/>. If it is, <paramref name="returnIfEqual"/> is returned,
/// otherwise, <paramref name="returnIfNotEqual" /> is returned.
/// </summary>
public static TResult IfEqualReturn<TValue, TResult>(this HtmlHelper html, TValue left, TValue right, TResult returnIfEqual, TResult returnIfNotEqual)
{
return EqualityComparer<TValue>.Default.Equals(left, right) ? returnIfEqual : returnIfNotEqual;
}
Notes:
- Use generics instead of
object
to avoid boxing.
- Use
EqualityComparer<TValue>
to check for equality. This class is very efficient, avoids boxing, and does a good job of handling the primitive types correctly, uses IEquatable<T>
if TValue
implements it, and correctly evaluates reference equality versus value equality depending on TValue
. It also will not throw an exception if left
or right
is null.
When you create any function (but extensions methods in particular), choosing a descriptive but succinct name is critical. Ideally, the name should be enough information for another developer to know what the function does without looking at its code.
- I chose
IfEqualReturn
because, to me, the most important thing to understand about the function is that it evaluates the equality of left
and right
to determine what to return-- remember, any boolean value can be used for a ternary expression, so GetValueTernary
leaves out the critical detail that this function specifically evaluates equality.
- Using XML comments is particularly important for extension methods. When you write your
<summary>
, imagine that another developer is reading your code, and explain what he would need to know to understand what the call will do. Keep it brief-- it should fit easily in a tooltip. If you feel like you need to explain more, add a <remarks>
element.
Here are some other suggestions.
The .NET Framework interface IEqualityComparer<T>
allows you to create classes that evaluate equality of a given type T
. The following function allows someone to pass in an instance, and falls back on EqualityComparer<T>.Default
if one is not specified.
public static TResult IfEqualReturn<TValue, TResult>(this HtmlHelper html, TValue left, TValue right, TResult resultIfEqual, TResult resultIfNotEqual, IEqualityComparer<TValue> equalityComparer = null)
{
if (equalityComparer == null)
equalityComparer = EqualityComparer<TValue>.Default;
return equalityComparer.Equals(left, right) ? resultIfEqual : resultIfNotEqual;
}
One place where this comes in handy is when comparing strings (see StringComparer). Usage:
var r1 = Html.IfEqualReturn("str1", "str2", true, false, StringComparer.Invariant); // r1 = false
var r2 = Html.IfEqualReturn("str1", "str1", true, false, StringComparer.Invariant); // r2 = true
var r3 = Html.IfEqualReturn("str1", "STR1", true, false, StringComparer.Invariant); // r3 = false
var r4 = Html.IfEqualReturn("str1", "STR1", true, false, StringComparer.InvariantIgnoreCase); // r4 = true
... or you could create one that uses a lambda expression:
public static TResult IfTrueThen<TValue, TResult>(this HtmlHelper html, TValue left, TValue right, TResult returnIfTrue, TResult returnIfFalse, Func<TValue, TValue, bool> evaluateFunc)
{
return evaluateFunc(left, right) ? returnIfTrue : returnIfFalse;
}
// Usage:
var r1 = Html.IfTrueThen(0, 1, true, false, (l, r) => l == r); // r1 = false
var r2 = Html.IfTrueThen("string", "STRING", true, false, (l, r) => String.Equals(l, r, StringComparison.InvariantIgnoreCase)); // r2 = true
Another way:
public static TResult IfTrueThen<TResult>(this HtmlHelper html, Func<HtmlHelper, bool> evaluateFunc, TResult resultIfTrue, TResult resultIfFalse)
{
return evaluateFunc(html) ? resultIfTrue : resultIfFalse;
}
// Usage:
int v1 = 0, v2 = 0;
var r1 = Html.IfTrueThen(h => v1 == v2, true, false); // r1 = true
v1 = 4;
var r2 = Html.IfTrueThen(h => v1 == v2, true, false); // r2 = false
var r3 = Html.IfTrueThen(h => (v1 - 4) == v2, true, false); // r3 = true
or...
<div class="@Html.IfTrueThen(h => Model.UserVoteTypeId == VoteType.UpVote, "us", "u")">...</div>
return (a.Equals(b) ? valueIfEqual : valueIfNotEqual).ToString()
\$\endgroup\$<div class="@(Model.UserVoteTypeId == VoteType.UpVote ? "us" : "u")">...</div>
? \$\endgroup\$