从构造函数启动了具有不同类的属性

时间:2019-08-01 17:07:48

标签: c# interface

我有一个类,其属性(SearchResults)必须为List<T>,其中T是我的搜索类之一,取决于条件

public class SearchGeneralResponse : ActionResponse
{
    public IList<ISearchRecord> SearchResults { get; set; }


    public SearchGeneralResponse(MbsObjectType searchType)
    {
        if(searchType == MbsObjectType.SourceRepo) SearchResults = new List<SearchRecord>();
        if(searchType == MbsObjectType.BuildConfiguration) SearchResults = new List<SearchRecordBuild>();
    }
}

我可以将新的SearchRecord投射到ISearchRecord。但是当我使用列表

this.SearchResults = new List<SearchRecord>();

我收到此错误:

  

不能将类型System.Collections.Generic.List'SearchRecord'隐式转换为System.Collections.Generic.List'ISearchRecord'

这是我的界面:

public interface ISearchRecord 
{

}

以及派生类之一:

public class SearchRecord : ISearchRecord
{
    public string Name { get; set; }

    public string Summary { get; set; }

}

如何创建List<T>属性,可以根据特定条件将其初始化为类的列表?

2 个答案:

答案 0 :(得分:2)

将类型转换添加到初始化程序中:

this.SearchResults = new List<SearchRecord>().Cast<ISearchRecord>().ToList();

答案 1 :(得分:2)

泛型提供了编译时类型的安全性,但是在这种情况下,您试图告诉编译器它应该只相信您不会有运行时问题。它的工作是不信任您:)

考虑如果允许此分配 并执行此操作,将会发生什么情况

IList<ISearchRecord> results;             // results is of type IList<ISearchRecord>
results = new List<SearchRecord>();       // but it holds a value of type List<SearchRecord>
results.Add(new SomeOtherSearchRecord()); // ERROR

由于属性SearchResults的类型为IList<ISearchRecord>,因此任何使用该属性的代码都可以将ISearchRecord any 实现分配给该列表的元素。因此,它需要始终ISearchRecord,而不是更具体的实现类型。

退后一步,考虑代码需要做什么的语义。 SearchResults是否应支持ISearchRecord的任何实现?如果始终要从SearchRecord进行分配,则使其具有特定的类型:

public IList<SearchRecord> SearchResults { get; set; }

或者,如果它需要是ISearchRecord的列表(以便它可以支持其他实现),则必须创建该类型的列表:

this.SearchResults = new List<ISearchRecord>();

编辑:另外,如果您的new List<>()只是一个虚构的示例,而您实际上是从其他位置获取列表,则仍然需要创建一个新列表。幸运的是,该列表中的引用仍然可以指向相同的对象,但是列表本身必须是正确的编译时类型。您可以使用以下方法实现此目标:

this.SearchResults = someOtherList.Cast<ISearchRecord>().ToList();

这将创建一个正确类型的新列表对象,其中包含与someOtherList相同的元素。