[英]JsonConvert.DeserializeObject throws an exception when attempting to deserialize byte[] to IEnumerable<byte>
[英]Exception when attempting to cast IEnumerable?
我還在學習C#項目的前幾周,我正在嘗試正確實現IEnumerable
接口。 我已經閱讀了許多教程/指南,但我似乎仍然做錯了什么。 我有一個強大的Java背景,所以我認為我對Java泛型的一些知識讓我理解它們如何在C#中工作。
我無法改變的類包含一個實例變量:
public IEnumerable<object> Items;
我想為它提供一個SampleDataSource
類的實例。 此類充當List
of MyObject
類型的存儲容器:
public class SampleDataSource : IEnumerable
{
public List<MyObject> Subjects { get; private set; }
public IEnumerator<MyObject> GetEnumerator()
{
return this.Cast<MyObject>().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
但是當我嘗試使用此代碼將此SampleDataSource
類的實例 SampleDataSource
轉換為IEnumerable<object>
:
Items = (IEnumerable<MyObject>)App.SampleData;
我收到一個例外:
附加信息:無法將類型為“Expression.Blend.SampleData.SampleDataSource.SampleDataSource”的對象強制轉換為'System.Collections.Generic.IEnumerable`1 [Expression.Blend.SampleData.SampleDataSource.MyObject]'。
但我不太明白為什么 - 我的SampleDataSource
是否正確地作為IEnumerable
正在返回包含MyObject
類型的枚舉器?
它不僅可以實現方法,而且必須實際實現接口。
在你的情況下,最好讓你的類實現適當的接口。
public class SampleDataSource : IEnumerable<MyObject>, IEnumerable
另一個潛在的對象是使用OfType<T>
來處理這個:
// returns enumerable of the items that are actually assignable to MyObject
IEnumerable<MyObject> values = theDataSource.OfType<MyObject>();
我已經意識到這個問題已經回答了,但是我錯過了對你問題背后問題的一個簡單解釋,所以這里有:
您無法將SampleDataSource
類分配給IEnumerable<object>
字段的原因是SampleDataSource
不實現IEnumerable<object>
。 雖然它確實實現了IEnumerable
,但這還不夠好,因為IEnumerable<object>
是IEnumerable
的子類型 。
由於接口協方差,如果它實現IEnumerable<MyObject>
,您將能夠將類分配給IEnumerable<object>
字段,前提是MyObject實際上是引用類型(即類)。 但是,這僅適用於C#4.0及更高版本。
Reed Copsey的回答沒有提到你可以聲明SampleDataSource類,因為IEnumerable<T>
繼承自IEnumerable
:
public class SampleDataSource : IEnumerable<MyObject>
此外,由於您只是包裝所包含的集合,因此通常會實現它:
public class SampleDataSource : IEnumerable<MyObject>
{
public List<MyObject> Subjects { get; private set; }
public IEnumerator<MyObject> GetEnumerator()
{
return Subjects.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
但是,從面向對象的角度來看,這是有問題的,因為您正在為列表提供公共讀寫訪問權限。 (setter是私有的這一事實意味着公眾不能重新分配列表引用,但它不會阻止它們在列表上調用Add
或Remove
或Clear
。)
另取在面向對象的問題是要問:如果一個SampleDataSource 包含 MyObjects序列,為什么會也是 MyObjects的序列? 而不是這樣做:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance;
也許你應該這樣做:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance.Subjects;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.