在使用C#构建List时使用通用类型和接口

时间:2016-05-25 15:50:45

标签: c# .net generics interface

我有以下界面:

public interface IModel
{
    string Code { get; set; }
    string Description { get; set; }
}

我有十几个实现的类,例如:

public interface Obj1 : IObj1
{
    string Code { get; set; }
    string Description { get; set; }
}

public interface Obj2 : IObj2
{
    string Code { get; set; }
    string Description { get; set; }
}

IObj1和IObj2都实现了IModel:

public interface IObj1 : IModel {}
public interface IObj2 : IModel {} 

在我的单元测试中,我使用每个对象的值创建模拟列表。目前我的代码如下所示:

public static List<IObj1> Obj1ListCacheMock()
{
    var list = new List<IObj1>();

    list.Add(new Obj1() { Code = "S1", Description = "Test 1" });
    list.Add(new Obj1() { Code = "S2", Description = "Test 2" });
    list.Add(new Obj1() { Code = "S3", Description = "Test 3" });

    return list;
}

public static List<IObj2> Obj2ListCacheMock()
{
    var list = new List<IObj1>();

    list.Add(new Obj2() { Code = "S1", Description = "Test 1" });
    list.Add(new Obj2() { Code = "S2", Description = "Test 2" });
    list.Add(new Obj2() { Code = "S3", Description = "Test 3" });

    return list;
}

我的目标是只有一个返回测试对象列表的方法。类似的东西:

public static List<IModel> Obj2ListCacheMock<IModel>()
{
    var list = new List<IModel>();

    list.Add(new { Code = "S1", Description = "Test 1" });
    list.Add(new { Code = "S2", Description = "Test 2" });
    list.Add(new { Code = "S2", Description = "Test 3" });

    return list;
}

此代码错误:

  

错误CS1503参数1:无法转换为&#39;&#39;到&#39; IModel&#39;

我如何开展这项工作或是否有更好的方法来实现我的目标?

2 个答案:

答案 0 :(得分:2)

您可以使用parameterless constructor

的约束来创建泛型方法
public static List<T> GetListCacheMock<T>() where T : IModel, new()
{
    var list = new List<T>();

    list.Add(new T { Code = "S1", Description = "Test 1" });
    list.Add(new T { Code = "S2", Description = "Test 2" });
    list.Add(new T { Code = "S2", Description = "Test 3" });

    return list;
}

然后,像这样使用它:

List<Obj1> obj1s = GetListCacheMock<Obj1>(); //Assuming Obj1 is class  with a parameterless constructor
List<Obj2> obj2s = GetListCacheMock<Obj2>(); //Same for Obj2

如果您的类没有无参数构造函数,则可以传递Func<T>来创建类型实例:

public static List<T> GetListCacheMock<T>(Func<T> getNew) where T : IModel
{
    var list = new List<T>();

    var item1 = getNew();
    item1.Code = "S1";
    item1.Description = "Test 1";

    list.Add(item1);
    ...

    return list;
}

最后

List<Obj1> obj1s = GetListCacheMock<Obj1>(() => new Obj1(...));

答案 1 :(得分:1)

您仍然需要指定要创建的对象。 这里:

new { Code = "S1", Description = "Test 1" }

您正在创建一个不实现您的IModel接口的匿名类型。

如果添加对象名称,它应该可以工作。

public static List<IModel> Obj2ListCacheMock<IModel>()
{
    var list = new List<IModel>();

    list.Add(new Obj1() { Code = "S1", Description = "Test 1" });
    list.Add(new Obj2() { Code = "S2", Description = "Test 2" });
    list.Add(new Obj1() { Code = "S2", Description = "Test 3" });

    return list;
}