我正在尝试创建一个单独的MVC视图来显示"详细信息"我的搜索结果页面,可以有多种不同类型(应用程序,人员,计算机,许可证等)...
鉴于所有这些不同的类型都没有相同的对象属性,甚至是相同的基本属性,我决定要做的就是在搜索视图中传递结果列表,到细节控制器。
但是,我在控制器内读回信息时遇到了问题......这是我到目前为止的代码(部分):
public ActionResult Details(int index)
{
List<object> SearchResults = TempData.ContainsKey("SearchItems") ? TempData["SearchItems"] as List<object> : null;
if(SearchResults == null)
{
//go to error page.
ViewBag.ErrorDescription = "Oups! Something went wrong trying to load the profile information. If you continue to see this error message, please contact the system administrator with the details below.";
ViewBag.ErrorMessage = "An internal error occurred: TempData object key not found.";
return View("Error");
}
if(SearchResults.Count == 0)
{
//go to error page.
ViewBag.ErrorDescription = "Oups! Something went wrong trying to load the profile information. If you continue to see this error message, please contact the system administrator with the details below.";
ViewBag.ErrorMessage = "An internal error occurred: TempData object contains no elements.";
return View("Error");
}
//I also check if the index is out of range and stuff...
object TypeUse = SearchResults[0];
//case statement and other actions are here...
}
到目前为止,我可以通过在调试器中查找TempData[SearchItems]
来查看列表,它会在我尝试强制转换为List<object>
时显示正确的信息,但是出于某种原因, SearchResults
变为空。
正如您在上面的代码中所看到的,我遵循的逻辑是:
所以我的问题有两个方面:
答案 0 :(得分:3)
You cannot cast a List<T>
to a List<object>
(除非T
object
)。您可以转换为IEnumerable<object>
并更改您的第一个&#34;对象提取:
IEnumerable<object> SearchResults =
TempData.ContainsKey("SearchItems") ?
TempData["SearchItems"] as IEnumerable<object> :
null;
...
object TypeUse = SearchResults.First();
答案 1 :(得分:2)
这是由于co variance and contra variance
说Cat
和Dog
都从Animal
继承。
您可能希望能够将List<Cat>
转换为List<Animal>
,例如
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
List<Animal> animals = (List<Animal>)cats;
Animal first = animals[0];
现在虽然看起来都很好,此代码实际上无法正常工作,如果实际允许此行为,那么您将如何应对
animals.Add(new Dog());
Dog
不是要存储到List<Cat>
的有效类型。
由于您想要提取基本类型的集合,您可以使用IEnumerable<Animal>
。
IEnumerable<Animal> animals = (IEnumerable<Animal>)cats;
Animal first = cats.First(); // using Linq;
请注意,出于类似的原因,您不能直接转回IEnumerable<Cat>
,因为并非每个Animal
都是Cat
。您可以使用Linq扩展方法OfType<Cat>()
或Cast<Cat>()
来执行此操作。
因此,在您的情况下,您需要SearchResults
为IEnumerable<object>
类型,或者甚至是所有可搜索类型继承的基本接口/类,允许您使用逻辑中的任何公共属性。
<强>后续强>
如果您使用的是.Net 4.5,则可以使用IReadonlyList<T>
代替IEnumerable<T>
。这提供了仍然提供计数和项目索引的额外优点。