类型T必须是引用类型,以便在使用接口时将其用作参数

时间:2017-11-30 06:54:50

标签: c# oop generics interface moq

我收到以下代码的错误

public static Moq.Mock<T> CreateInstanceOfIMock<T>() {
    return new Moq.Mock<T>();
}

我使用引用的class类型导致solved错误。见下面的代码

public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : class
{
    return new Moq.Mock<T>();
}

现在,我想使用var mockColorsRepository = new Moq.Mock<IColorsRepository>();将此generics代码移动到公共代码中。此处IColorsRepositoryinterface。所以我为T而不是class创建了一个接口参考,如下面的代码

public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : interface
{
    return new Moq.Mock<T>();
}

但是我遇到The type T must be a reference type in order to use it as parameter错误。如何将interface代替class引用至T。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:5)

C#中没有通用约束来强制类型参数是一个接口。但where T : class 确实&#34;其中T是参考类型&#34; - 它包括接口。

如果你想强制T是一个接口而不是一个类,你可以使用方法中的typeof(T)执行执行时间检查,但在这种情况下听起来好像你没有&# 39;真的需要将它限制为一个接口。

我不确定&#34;帮助&#34;方法特别有用 - 如果你比较:

var mock = Helper.CreateInstanceOfIMock<Foo>();

var mock = new Moq.Mock<Foo>();

或者甚至(除非你的某个地方有Mock<T>作为另一种类型)只是一个using Moq;指令和

var mock = new Mock<T>();

后者似乎同样可读且更短......如果你要在你的方法中添加更多逻辑,这是有道理的,但如果它只是打算调用构造函数,我就不会# 39;我觉得我很烦。

答案 1 :(得分:5)

generic type constaints中的

classstruct与用于声明类或结构类型的classstruct声明的含义不同。相反,它们仅限制泛型类型参数是引用类型class)还是值类型struct)。

所以当你where T : class {em>

}时,T需要成为一个类,你说T需要是一个引用类型。类似地,struct代表值类型。

接口本身没有此属性,因此接口可以由引用类型和值类型实现。因此,将您的类型限制为接口并不是真的有意义。

在您的情况下,Moq要求您传递引用类型,因此您需要在所有辅助方法中传递性地继承该类型约束:

public static Moq.Mock<T> CreateInstanceOfIMock<T>()
    where T : class
{
    return new Moq.Mock<T>();
}

这就是创建任何有效类型的模拟所需要做的全部工作。您可以使用CreateInstanceOfIMock<IColorsRepository>()或任何其他类型的界面使用它。

当然,在这一点上,该方法并没有真正有意义,因为它不会给你带来任何好处,而不仅仅是自己实例化模拟。