
[英]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.