开发者

Overriding generic IEnumerable interface in child class

I am developing an ORM. I want my collection objects to be able to used in Linq. The classes I wrote here are simplified for the sake of clarity. The array containing the entity objects is in the CollectionBase class.

class EntityBase
{
    public int fieldBase;
}

class EntityChild : EntityBase
{
    public int fieldChild;
}

class CollectionBase : IEnumerable<EntityBase>
{
    protected EntityBase[] itemArray;

    //implementing the IEnumerable<EntityBase> is here. GetEnumerator method returns IEnumerator<EntityBase>

}

class CollectionChild : CollectionBase, IEnumerable<EntityChild>
{
    public CollectionChild()
    {
        itemArray = new EntityChild[5]; //this is just an example.
    }
    //implementing the IEnumerable<EntityChild> is here. GetEnumerator method returns IEnumerator<EntityChild
}

There are several things that I tried.

If CollectionChild does not extend IEnumerable, EntityChild's own fields cannot be reachable in this code:

var list = from c in childCollection
where c.fieldChild == 1; // c references to an EntityBase object.
select c;

If CollectionChild extends IEnumerable, it is not even possible to use CollectionChild in Linq.

Error occures: "Could not find an implementation of the query pattern for source type 'Generic_IEnumerableSample.CollectionChild'.'Where' not found. Consider explicitly specifying the type of the range variable 'childCollection'."

I tried to find some way to inherit the class (in Collection开发者_开发技巧Base that implements IEnumerator) in CollectionChild as IEnumerator class. It did not work, because it is not possible to override the methods that return different Enumerators.

It is still possible to not implement the IEnumerator interface for the base collection class, and implement for all child collection classes. But it seems like a non OODesign appraoch.

Must I change my design, or is there any way to completely override the IEnumerable methods or effects?


Adjust your class this way:

public class CollectionBase<T> : IEnumerable<T>
  where T: EntityBase
{
    protected EntityBase[] itemArray;

    //implementing the IEnumerable<EntityBase> is here. GetEnumerator method returns IEnumerator<EntityBase>

}

That way, the base class will know the underlying type.

HTH.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜