2015-04-03 160 views
1

我有一個動作要搜索的人的控制,它會返回anonymouse的列表:無法將IEnumerable的匿名類型轉換爲IEnumerable <dynamic>?

[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

也許'var result = target.GetResult(「Ashley」)爲OkNegotiatedContentResult >;'在你的測試方法中適合你......? – stefankmitph 2015-04-03 06:53:13

+0

@stefankmitph'result'將始終爲空。 – 2015-04-03 07:07:39

回答

1

您不是將一些動態轉換爲其他參數化類型的動態但具體的參數化類型。你的代碼遭受的問題稱爲協變和逆變。不幸的是,class不支持協變/逆變(class總是不變)。 可能的解決方法:

var result = ((dynamic)target).GetResult("Ashley"); 
//result is of type OkNegotiatedContentResult<...> 
var content = (IEnumerable<dynamic>)result.Content; 

由於IEnumerable是協變,即投將工作。

更多關於協方差和逆變on MSDN.

+0

謝謝,這個作品:-) – xinfli 2015-04-21 05:07:49

0

您可以用

IHttpActionResult result = target.GetResult("Ashley"); 
IEnumerable<dynamic> content = (IEnumerable<dynamic>)((dynamic)result).Content; 

您使用dynamic使用屬性.Content嘗試將返回IEnumerable<T>,然後用協方差丟給IEnumerable<object>/IEnumerable<dynamic> (它們相當於CLR級別...... dynamic是由編譯器完成的一項神奇功能)

請注意,如果OkNegotiatedContentResultT是一個值類型,那麼這將不起作用,但在您的情況下它是引用類型,所以沒有問題。

+1

我也有類似的問題。您的解決方案可用於測試返回結果。但是如果我想測試控制器是否返回'''OkNegotiationResult'''或者不呢? – 2015-05-20 02:49:37

+0

這應該工作:Assert.AreEqual(typeof(OkNegotiatedContentResult <>),result.GetType()。GetGenericTypeDefinition()); – 2016-10-21 14:25:18

相關問題