Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating Generic Iterator

Status
Not open for further replies.

majkinetor

Programmer
Feb 21, 2006
88
RS
Hello.

I have number of different classes, C1 ... Cn impelemnting some objects I store in database.

For each class I have associated class BookOfClass that implements IEnumerable and walks over collection of all objects of that particular class.

I want to convert number of BookOfClass classes to 1 generic class Book<Class>.

This is how book looks like for lets say Class Person which book is named BookOfPersons:
Code:
    public class BookOfPersons : Book, IEnumerable
    {
        class BookEnum: IEnumerator
        {
            private DataTable Table;
            int position = -1;

            public BookEnum(DataTable t)
            {
                Table = t;
            }

            public bool MoveNext()
            {
                position++;
                return (position < Table.Rows.Count);
            }

            public void Reset()
            {
                position = -1;
            }

            public object Current
            {
                get
                {
                    try
                    {
                        return new Person( Table.Rows[position] );
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
        }

        public BookOfPersons() : this( null )
        {

        }
        public BookOfPersons(string Filter) :base (Filter)
        {
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new BookEnum( this.Table );  //Table is property of base class Book
        }
    }

As you can see, the only thing that is connected to actual Person class is in BookEnum.Current method. I tried to create generic to be able to do this with any class, as they all follow the same pattern (In above example, BookOf<Person>).

I regualry added <T> in definition of BookOf class and replaced
return new Person( Table.Rows[position] )
with
return new T( Table.Rows[position] )

but compiler complained that I can't do that without some constraints. I added new() among constraints but I don't call parameterless constructor. I also added base class of my entire framework among constraints but nothing helped.

It seems that I can not use generic type to instantiate particular class that have common constructor.

Is there any way that I can do this ?

The latest code I couldn't fix is this:

Code:
   public class Book<T> : Book, IEnumerable where T: new()
    {
        class BookEnum : IEnumerator
        {
            private DataTable Table;
            int position = -1;

            public BookEnum(DataTable t)
            {
                this.Table = t;
            }

            public bool MoveNext()
            {
                position++;
                return (position < Table.Rows.Count);
            }

            public void Reset()
            {
                position = -1;
            }

            public object Current
            {
                get
                {
                    try
                    {
                        return new T(Table.Rows[position]);
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
        }

        public Book()
            : this(null)
        {

        }
        public Book(string Filter)
            : base(Filter)
        {
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new BookEnum(this.Table);
        }
    }

I get error "cannot provide arguments when creating an instance of a variable type". Help says "If you need to call another constructor, consider using a class type constraint or interface constraint."

When I change
Code:
   public class Book<T> : Book, IEnumerable where T: Person, new()

it also reports the same error....

I would appreciate any help.

In short the problem is how to call non parameterless constructor of generic type

Thank you
 
Well, I solved this problem by using System.Reflection.

This is spawning constructor:

Code:
Type[] types = new Type[1] { typeof(DataRow) };
Type t = typeof(T);
ConstructorInfo ci = t.GetConstructor( types );
return ci.Invoke( new Object[] { Table.Rows[ position ] } );
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top