If I have an interface for all poolable objects and I require each poolable object to have two delegated methods.

public delegate T CreateNewObjectGame(Game1 game);
public delegate bool ValidateObject(T obj);

How can I make sure they are always required when inheriting from an interface when an interface can't declare types?

interface IPoolable
    {
        delegate bool ValidateObject(T obj);
        delegate T CreateNewObjectGame(Game1 game);
    }

Recommended Answers

All 26 Replies

You need to use the event keyword and put the delegate outside the interface.
Like this:

delegate bool ValidateObject<T>(T obj);
    delegate T CreateNewObjectGame<T>(Game1 game);

    interface Interface1<T>
    {
        event ValidateObject<T> Validate;
        event CreateNewObjectGame<T> CreateNewGame;
    }

    class testClass : Interface1<int>
    {
        #region Interface1<int> Members

        public event ValidateObject<int> Validate;

        public event CreateNewObjectGame<int> CreateNewGame;

        #endregion
    }

This compiles but I have not tested it to see how well it work.

(I am sure int is not an appropriate type for your app but it works for demonstration only.)

I get the following error,


The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

with this code

delegate bool ValidateObject(T obj);
    delegate T CreateNewObjectGame(Game1 game);

    interface IPoolable<T>
    {
        event ValidateObject<T> Validate;
        event CreateNewObjectGame<T> CreateNewObject;
    }

Not sure what the correct term is but you need the generic type identifier <T> on the delegate definitions otherwise the compiler does not know what to do with T.

delegate bool ValidateObject<T>(T obj);
delegate T CreateNewObjectGame<T>(Game1 game);

Aye that works! Thank you.

delegate bool ValidateObject<T>(T obj);
    delegate T CreateNewObjectGame<T>(Game1 game);

    interface IPoolable<T> where T : class
    {
        event ValidateObject<T> Validate;
        event CreateNewObjectGame<T> CreateNewObject;
    }

The problem is now hooking up the events as I get


'Foo' does not implement interface member 'IPoolable<Foo>.CreateNewObject'
'Foo' does not implement interface member 'IPoolable<Foo>.Validate'

Here are the two methods I am trying to hook up.

// Resource pool delegate method
        public static Foo CreateNewObject(Game1 game)
        {
            return new Foo(game);
        }

        // Resource pool delegate method
        public static bool Validate(Foo foo)
        {
            return foo.IsAlive;
        }

Any suggestions?

Are you sure you want a generic interface or do you really need generic static methods?

Any object that can be pooled will require

interface IPoolable<T> where T : class
    {
        event ValidateObject<T> Validate;
        event CreateNewObjectGame<T> CreateNewObject;

        public bool isValid;
    }

The pool class requires objects to be created and validated

public ResourcePool(Game1 game, int allocation, ValidateObject objectCheck, CreateNewObjectGame objectCreate, bool isWrappable)
        {
            this.isWrappable = isWrappable;
            numberOfInvalidObjects = allocation;
            this.objectCheck = objectCheck;
            objects = new T[allocation];

            for (int i = 0; i < allocation; ++i)
            {
                T t = objectCreate(game);
                objects[i] = t;
            }
        }

I would like to be able to pool any type of class that derives from IPoolable.

Do you think I have gone down the wrong route or is what I am doing logical?

An interface defines a set of methods and properties that are to be implemented by a class. For what you want to do I think you will need a combination of an interface and generic static methods.
What do you think of this?

public interface IPoolable
    {
        bool IsAlive { get; }
        void InitGame(Game1 game);
    }

    public class foo : IPoolable
    {
        bool _IsAlive = false;

        bool IPoolable.IsAlive
        {
            get { return _IsAlive; }
        }

        void IPoolable.InitGame(Game1 game)
        {
            // do initialisation using game
            _IsAlive = true;
        }
    }

    public class Game1
    {
        // Resource pool delegate method
        public static T CreateNewObject<T>(Game1 game) where T : IPoolable, new()
        {
            T foo = new T();
            ((IPoolable)foo).InitGame(game);
            return foo;
        }

        // Resource pool delegate method
        public static bool Validate<T>(T foo) where T : IPoolable
        {
            return ((IPoolable)foo).IsAlive;
        }

        public bool Test()
        {
            foo test = Game1.CreateNewObject<foo>(this);
            return Game1.Validate<foo>(test);
        }
    }

That's moving away from the idea I had. It might not be feasible but I intended to have an IPoolable interface that contained the events so all derived classes must have the events hooked up in them.

This is because the ResourcePool class requires the delegates being passed in and I would be reminded to create the delegates for each pooled object.

interface IPoolable<T> where T : class
    {
        event ValidateObject<T> Validate;               // Required to validate the object (using IsValid as the boolean value)
        event CreateNewObjectGame<T> CreateNewObject;   // Required to create a new instance of the object to store in the pool

        bool IsValid { get; set; }                      // Require to tell pool if object is in use or not
    }

Can I not hook up the events somehow?

EDIT:

Could I get away with

interface IPoolable
    {
        void CreateNewObject(Game1 game);
        bool IsValid { get; set; }                      // Require to tell pool if object is in use or not
    }

for the 2 required delegates. How could I return a new instance inside the class if I can't make it static though?

Much of how interfaces and generic definition work is determined by where and how you want the functions to operate.
You have not made that clear in you question.
Please explain in a more detail the object interaction you wish to achieve.
[Edit](And the current interaction that you wish to retain)

Sorry for the confusion, here's my best explanation.

I wish to have an interface that defines the minimum parameters required in order to create a ResourcePool.

The pool has two delegates:

public delegate bool ValidateObject(T obj);
public delegate T CreateNewObjectGame(Game1 game);

One checks for a boolean value whether the object isValid or not.

This will require

bool IsValid{get; set;}

in the interface.

My problem lies with the two delegate methods. I must have two methods in the interface that can be passed to the delegates.

One of which returns the IsValid property (maybe this isn't needed and only the boolean is required?)

The other method in the interface should return a new instance of the object (class T) and allow Game1 to be passed in as an argument.

I understood all that already. It is the following that I am not sure about.
What form does the ResourcePool take (I think it is a class)?
Is it for a single object type or many types (I think just one type)?
Would it be OK to have this as a generic class (e.g. class ResourcePool<T> {...} )
Please explain why you think you need static methods and where you think these should be located.
How and where is the ValidateObject method to be used?
Is CreateNewObjectGame only used in the constructor of ResourcePool?
If foo is a derived class (which I suspect it is) have you considered adding these methods to the base class as abstract methods?

A few things about delegates:
A delegate is just a type definition for a function pointer.
They define the required prototype and provide strong typing for function pointers.
They are not pointers to functions themselves.

[Edit]

Could I get away with

interface IPoolable
    {
        void CreateNewObject(Game1 game);
        bool IsValid { get; set; }                      // Require to tell pool if object is in use or not
    }

You might also consider

interface IPoolable
    {
        static object CreateNewObject(Game1 game);  //<-- added static keyword
        bool IsValid { get; set; }                      // Require to tell pool if object is in use or not
    }

You might also consider

interface IPoolable
    {
        static object CreateNewObject(Game1 game);  //<-- added static keyword
        bool IsValid { get; set; }                      // Require to tell pool if object is in use or not
    }

I don't think C# allows the use of the static keyword in the interfaces as I get this error message.


The modifier 'static' is not valid for this item

What form does the ResourcePool take (I think it is a class)?

It is indeed a class with the following methods.

public ResourcePool(Game1 game, int allocation, ValidateObject objectCheck, CreateNewObjectGame objectCreate, bool isWrappable)
        {
            this.isWrappable = isWrappable;
            numberOfInvalidObjects = allocation;
            this.objectCheck = objectCheck;
            objects = new T[allocation];

            for (int i = 0; i < allocation; ++i)
            {
                T t = objectCreate(game);
                objects[i] = t;
            }
        }

        public T GetNewValidObject()
        {
            if (numberOfInvalidObjects > 0)
            {
                // Reset the wrap index to oldest object when there are invalid (unused) objects
                wrapIndex = objects.Length;
                return objects[--numberOfInvalidObjects];
            }
            else if (isWrappable)
            {
                if (wrapIndex == 0)
                {
                    wrapIndex = objects.Length;
                }

                // Overwrite the oldest object in the pool if there are no free objects
                return objects[--wrapIndex];
            }

            return null;
        }


        public void InvalidateAllObjects()
        {
            numberOfInvalidObjects = objects.Length;
        }


        public void ValidateObjects()
        {
            for (int i = numberOfInvalidObjects; i < objects.Length; ++i)
            {
                T o = objects[i];

                if (!objectCheck(o))
                {
                    if (i != numberOfInvalidObjects)
                    {
                        objects[i] = objects[numberOfInvalidObjects];
                        objects[numberOfInvalidObjects] = o;
                    }

                    numberOfInvalidObjects++;
                }
            }
        }

Is it for a single object type or many types (I think just one type)?

A new instance of the class is used for each single object type. Only one type per instance.

If foo is a derived class (which I suspect it is) have you considered adding these methods to the base class as abstract methods?

Foo is derived from IPoolable.

Please explain why you think you need static methods and where you think these should be located.

The static method is used because creating a new instance is the same for all instances of a class that derives from IPoolable. If it were not static then I would have to create a new instance and then pass the method that creates a new instance from that instance into CreateNewObject.

Thanks for sticking with this.

Perhaps using an abstract class is more what you need.

abstract class PoolableBase<T> where T : PoolableBase<T>, new()
    {
        public static T CreateNew(Game1 game)
        {
            T obj = new T();
            obj.InitGame(game);
            return obj;
        }

        protected abstract void InitGame(Game1 game);

        public abstract bool IsValid { get; set; }

    }

    class foo : PoolableBase<foo>
    {
        bool _IsValid = true;
        Game1 _game;

        public foo()
        {
            // do base init
        }

        protected override void InitGame(Game1 game)
        {
            _game = game;
            // do game specific init
        }

        public override bool IsValid
        {
            get { return _IsValid; }
            set { _IsValid = value; }
        }
    }


    class ResourcePool<T> where T : PoolableBase<T>, new()
    {
        bool isWrappable;
        int numberOfInvalidObjects;
        public T[] objects;

        public ResourcePool(Game1 game, int allocation, bool isWrappable)
        {
            this.isWrappable = isWrappable;
            numberOfInvalidObjects = allocation;
            objects = new T[allocation];

            for (int i = 0; i < allocation; ++i)
            {
                T t = PoolableBase<T>.CreateNew(game); //<-- use generic create new
                objects[i] = t;
            }
        }

        public void ValidateObjects()
        {
            for (int i = numberOfInvalidObjects; i < objects.Length; ++i)
            {
                T o = objects[i];

                if (!o.IsValid) //<-- use IsValid method directly
                {
                    if (i != numberOfInvalidObjects)
                    {
                        objects[i] = objects[numberOfInvalidObjects];
                        objects[numberOfInvalidObjects] = o;
                    }

                    numberOfInvalidObjects++;
                }
            }
        }
    }

    class Game1
    {
        public ResourcePool<foo> res;

        public void Test()
        {
            res = new ResourcePool<foo>(this, 2, false);
            res.ValidateObjects();
        }
    }

Using an abstract base class leads to problems when trying to create a Dictionary of pools.

Dictionary<string, ResourcePool<Poolable<T>> pools = new Dictionary<string,ResourcePool<Poolable<T>>>();

The dictionary will not accept generic T.

How can I just have one Dictionary of all pools using a base class?

It's not that the base class is abstact, it's because it's generic.
I'll have a think and get back to you.

Thanks Nick. This is a tricky one.

What you need is a common base type for each of the ResourcePool objects.
If you define an interface say IResourcePool this can be used as a common interface for your pools collection.

interface IResourcePool
    {
        void ValidateObjects();
        // any other method to be common to all ResourcePool types
    }

You can then use this in you pools dictionary.

public Dictionary<string, IResourcePool> pools = new Dictionary<string, IResourcePool>();

        public void Test()
        {
            pools.Add("foo", new ResourcePool<foo>(this, 2, false));
            pools["foo"].ValidateObjects();
        }

Remember to implement the interface in the ResorcePool<T> class.

class ResourcePool<T> : IResourcePool where T : PoolableBase<T>, new()
    {

I think that should get you going.

A little bit about using generic types (as I see them).

The T in a generic definition is not a type. It is a placeholder for a type that is later defined when the method (or class) is called (or created).

A generic method does not exist if it is never called. It is a template method that the compiler uses to build the actual method by replacing the T with the type put in the <>. For each type used with the method a seperate method is created in the build output.

static T FactoryBuilder<T>() where T : new()
        { return new T(); }

            Class3 cls3 = FactoryBuilder<Class3>();
            Class6 cls6 = FactoryBuilder<Class6>();

In the above example FactoryBuilder<T> is the template that the compiler uses to generate two methods, FactoryBuilder<Class3>() and FactoryBuilder<Class6>(). It does not exist on its own.

This use of generics allows us to create standard methods without defining all the different type overloads.

Similarly with generic classes. These do not exist unless an instance is created.
They are a template for a class that the compiler generates when it see the class being created.

So the code samples above class ResourcePool<T> { ... } defines a template class and new ResourcePool<foo>(...) instructs the compiler to create a class using this template, replacing T with foo.

Hope this help you better understand generic types.

So does Foo now inherit from IResourcePool,

public class Foo : IResourcePool

PoolableBase,

public class Foo : PoolableBase<Foo>

or both?

Foo is derived from PoolBase<Foo> as in this post.
(Except ResourcePool<T> is now derived from IResourcePool).

I hope I understood the structure that you are trying to achieve correctly.
This is what I think is what you want:

  • Several poolable classes that can be members of a pool (foo1, foo2, foo3 etc.).
  • These must derive from a common base class to enforce certain functionality (defined using generics to minimise code duplication) PoolabeBase<T>.
  • A seperate pool class for each type (defined using generics to minimise code duplication) ResourcePool<T>.
  • A Dictionary object containing several pools thus requiring each pool to implement a common interface (IResourcePool).

If you are unsure of how any of the code is working please ask and I'll try to explain.
There is no point in you using this code if you do not understand it; after all it will be you that must maintain it.

I've come to a compromise. This is what I would like to use and it appears to work with Dictionaries/Lists.

public interface IPoolable 
    {
        bool IsValid { get; set; }
    }

    public class ResourcePool<T> where T : class, IPoolable
    {
        bool isWrappable;
        int wrapIndex;
        int numberOfInvalidObjects;
        T[] objects;

        public delegate T CreateNewObjectGame(Game1 game);

        public ResourcePool(Game1 game, int allocation, CreateNewObjectGame createNew, bool isWrappable)
        {
            this.isWrappable = isWrappable;
            numberOfInvalidObjects = allocation;
            objects = new T[allocation];

            for (int i = 0; i < allocation; ++i)
            {
                objects[i] = createNew(game);
            }
        }

        public T GetNewValidObject()
        {
            if (numberOfInvalidObjects > 0)
            {
                // Reset the wrap index to oldest object when there are invalid (unused) objects
                wrapIndex = objects.Length;
                return objects[--numberOfInvalidObjects];
            }
            else if (isWrappable)
            {
                if (wrapIndex == 0)
                {
                    wrapIndex = objects.Length;
                }

                // Overwrite the oldest object in the pool if there are no free objects
                return objects[--wrapIndex];
            }

            return null;
        }

        public void InvalidateAllObjects()
        {
            numberOfInvalidObjects = objects.Length;
        }

        public void ValidateObjects()
        {
            for (int i = numberOfInvalidObjects; i < objects.Length; ++i)
            {
                T o = objects[i];

                if (o.IsValid)
                {
                    if (i != numberOfInvalidObjects)
                    {
                        objects[i] = objects[numberOfInvalidObjects];
                        objects[numberOfInvalidObjects] = o;
                    }

                    numberOfInvalidObjects++;
                }
            }
        }

Please let me know what you think.

Also, a huge thank you for all your help in this area. I've learned a lot from your posts.

EDIT: Spoke too soon, can't convert from Foo to IPoolable even though Foo inherits from IPoolable, why is this happening?

class Foo : IPoolable
    {
        Game1 game;
        bool isValid;

        public Foo(Game1 game)
        {
            this.game = game;
        }

        public static Foo Instance(Game1 game)
        {
            return new Foo(game);
        }

        public bool IsValid
        {
            get { return isValid; }
            set { isValid = value; }
        }
    }
Dictionary<string, ResourcePool<IPoolable>> pools = new Dictionary<string, ResourcePool<IPoolable>>(10);
            pools.Add("Foo", new ResourcePool<Foo>(this, 10, Foo.Instance, false));

EDIT: Spoke too soon, can't convert from Foo to IPoolable even though Foo inherits from IPoolable, why is this happening?

Have you solved this now or is this still an issue?

It is still an issue. I would like a Dictionary of IPoolable Resource Pools that have access to the classes' IsValid property.

Each class must be derived from IPoolable to make use of the IsValid property and be stored in the Dictionary.

I can't convert Foo to IPoolable in a way that the Dictionary is happy with though, even though it inherits from that interface.

What errors do you get and where?

Here's the Foo class.

class Foo : IPoolable
    {
        Game1 game;
        bool isValid;

        public Foo(Game1 game)
        {
            this.game = game;
        }

        public static Foo Instance(Game1 game)
        {
            return new Foo(game);
        }

        public bool IsValid
        {
            get { return isValid; }
            set { isValid = value; }
        }
    }

This is what the Pool class T is derived from.

public class ResourcePool<T> where T : class, IPoolable

These lines are causing the errors.

Dictionary<string, ResourcePool<IPoolable>> pools = new Dictionary<string, ResourcePool<IPoolable>>(10);
            pools.Add("Foo", new ResourcePool<Foo>(this, 10, Foo.Instance, false));

The errors are

The best overloaded method match for 'System.Collections.Generic.Dictionary<string,ResourcePool<IPoolable>>.Add(string, ResourcePool<IPoolable>)' has some invalid arguments

and

Argument '2': cannot convert from 'ResourcePool<Foo>' to 'ResourcePool<IPoolable>'

ResourcePool<IPoolable> is a seperate class to ResourcePool<Foo>.
They are not the same. They do not even derive from the same class.
Although you have used the same generic template to define each class, they are distinct classes.
Therefore a dictionary of ResourcePool<IPoolable> can not contain ResourcePool<Foo> objects.
This is why I had a common IResourcePool in my previous solution.
You need "A Dictionary object containing several pools thus requiring each pool to implement a common interface (IResourcePool)."

So how can I make sure each pool implements an IResourcePool interface but also has access to the IPoolable.IsValid property.

At the same time all passed in classes T must implement a common interface that has IsValid as a property?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.