尝试投射IEnumerable时出现异常?
我仍然在学习C#的项目我的头几周,我试图正确地执行IEnumerable
接口。我已经阅读了一些教程/指南,但我似乎仍然在做一些不正确的事情。我有一个强大的Java背景,所以我认为我对Java泛型的一些了解让我理解他们如何在C#中工作。尝试投射IEnumerable时出现异常?
一类我不能改变包含一个实例变量:
public IEnumerable<object> Items;
而且我想提供它与我的SampleDataSource
类的一个实例。此类充当一个MyObject
的List
类型的存储容器:
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
类的实例到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
否则,您可以使用类似linfu的东西来鸭子键入您的类到界面。
的其他潜在目的是利用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<object>
字段是否实现IEnumerable<MyObject>
,条件是为MyObject实际上引用类型(即,一类)。这仅适用于C#4。0和更高版本,但是。
里德·科普塞的回答并没有提到,你可以这样声明SampleDataSource类,因为从IEnumerable
IEnumerable<T>
继承:
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();
}
}
这是从面向对象的角度有问题,不过,因为你给到列表中的公共读写访问。 (事实上,二传手是私有意味着公众无法重新分配名单参考,但并不妨碍他们从名单上调用Add
或Remove
或Clear
。)
另取在面向对象的问题会问:如果一个SampleDataSource 包含的一个MyObjects序列,为什么它也会是的一个MyObjects序列?相反,这样做的:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance;
也许你应该这样做:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance.Subjects;
你能更具体?它在这里没有正确实现接口:`SampleDataSource:IEnumerable`? – 2011-12-16 00:32:21