我有一个搜索控制器中的人的动作,它会返回一个匿名列表:
[UnitOfWork]
[HttpGet, Route("api/Search/People")]
public virtual IHttpActionResult GetResult(string keyword)
{
// ...
var result = peopleList.Select(x => new
{
PersonId = x.Id.Value,
EmploymentNumber = x.EmploymentNumber,
FirstName = x.Name.FirstName,
LastName = x.Name.LastName,
Email = x.Email
});
return Ok(result);
}
以下是该方法的测试用例:
[Test]
public void ShouldSearchPeople()
{
// Mocks...
var target = new PeopleSearchController(searchRepository, personRepository, new FakePermissionProvider());
// Error here
var result = (OkNegotiatedContentResult<IEnumerable<dynamic>>)target.GetResult("Ashley");
Assert.NotNull(peopleList);
// Other assert...
}
然后我收到如下错误:
System.InvalidCastException: Unable to cast object of type
'System.Web.Http.Results.OkNegotiatedContentResult`1[System.Collections.Generic.IEnumerable`1[<>f__AnonymousType1e`5[System.String,System.String,System.String,System.Guid,System.String]]]'
to type
'System.Web.Http.Results.OkNegotiatedContentResult`1[System.Collections.Generic.IEnumerable`1[System.Object]]'.
似乎IEnumerable与类或单个匿名对于这样的转换是可以的,但IEnumerable与匿名不起作用。
我该如何进行此类转换?感谢。
答案 0 :(得分:1)
你没有将一些动态的,但具体的参数化类型转换为其他参数化类型。您的代码遇到的问题称为协方差和逆变。遗憾的是,class
不支持协方差/逆变(class
始终不变)。
可能的解决方法:
var result = ((dynamic)target).GetResult("Ashley");
//result is of type OkNegotiatedContentResult<...>
var content = (IEnumerable<dynamic>)result.Content;
由于IEnumerable
是协变的,因此该演员阵容将起作用。
有关协方差和逆变的更多信息on MSDN.
答案 1 :(得分:0)
您可以尝试使用
IHttpActionResult result = target.GetResult("Ashley");
IEnumerable<dynamic> content = (IEnumerable<dynamic>)((dynamic)result).Content;
您使用dynamic
来使用将返回.Content
的属性IEnumerable<T>
,然后使用协方差将其转换为IEnumerable<object>
/ IEnumerable<dynamic>
(他们在CLR级别上是等效的...... dynamic
是编译器完成的一项神奇工具)
请注意,如果T
的{{1}}是值类型,则无效,但在您的情况下,它是引用类型,因此没有问题。