我有一个类,其属性(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>
属性,可以根据特定条件将其初始化为类的列表?
答案 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
相同的元素。