【问题标题】:Workaround for generics with static methods使用静态方法的泛型的解决方法
【发布时间】:2016-02-22 09:26:18
【问题描述】:

我正在实现一个类似于NUnit's Assert 的自定义 Assert 类。

我们使用 StyleCop 规则打开了 Sonar,它抱怨我应该始终使用泛型而不是 object。如果我将我的类更改为泛型类,那么我就会陷入泛型类不能有静态方法的规则。

例如,考虑以下代码(我当前方法的一个非常简化的版本):

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);
    }
}

在我看来,在 Assert 类中包含实例方法没有任何意义。当想要使用 TestCases 时,通用方法会迫使我做这样的事情(未经测试):

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

我怎样才能最好地重构这个类以符合这两个规则?

【问题讨论】:

  • 你能用代码举例吗?你考虑过扩展方法吗?
  • 类不必是通用的。改为使用通用方法。

标签: c# generics


【解决方案1】:

我会问一个不同的问题:你为什么需要这样的方法?

Assert.PropertyHasValue(foo, "bar", true)Assert.AreEqual(foo.bar, true)不一样吗?

是:

  • 清洁剂
  • 没有机会在属性名称中打错字
  • 获得编译时安全性

如果您确实需要这样做,您可能希望使用 Func&lt;U, T&gt; 而不是 string 来指定您的属性:

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);
    }
}

【讨论】:

  • 我为什么不吃蓝色药丸?
猜你喜欢
  • 2010-10-16
  • 2012-08-26
  • 2013-11-23
  • 1970-01-01
  • 2011-07-14
  • 2012-12-04
  • 1970-01-01
  • 2012-02-10
  • 2023-03-20
相关资源
最近更新 更多