Samir Aguiar
Samir Aguiar

Reputation: 2559

Workaround for generics with static methods

I'm implementing a custom Assert class similar to NUnit's Assert.

We have Sonar turned on with StyleCop rules and it complains that I should always use generics instead of object. If I change my class to a generic one, then I fall into the rule that generic classes cannot have static methods.

For example, consider this code (a very simplified version of my current method):

public class Assert
{
    public static void PropertyHasValue(object obj, string propertyName, object expectedValue)
    {
        var value = obj.GetType().GetProperty(propertyName).GetValue(obj, null);
        Assert.AreEqual(expectedValue, value);
    }
}

Having instance methods in an Assert class wouldn't make any sense in my opnion. A generic method would force me to do something like this (untested) when wanting to use TestCases:

[TestCase("someProperty", 10)]
[TestCase("anotherProperty", "someString")]
public void TestMethod(string propertyName, object expectedValue)
{
    Assert.PropertyHasValue<object>(myObj, propertyName, expectedValue);
}

How could I best refactor this class to comply with both of these rules?

Upvotes: 0

Views: 63

Answers (1)

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

I would ask a different question: why would you ever need method like this?

Isn't Assert.PropertyHasValue(foo, "bar", true) the same as Assert.AreEqual(foo.bar, true)?

It's:

  • cleaner
  • no chance to make a typo in property name
  • you get compile time safety

If you really need to do that, you'd probably want to use Func<U, T> instead of string to specify your properties:

public static class Assert
{
    public static void PropertyHasValue<T,U>(T obj, Func<T, U> propertyGetter, U expectedValue)
    {
        var value = propertyGetter(obj);
        Assert.AreEqual(expectedValue, value);
    }
}

Upvotes: 4

Related Questions