Click here to Skip to main content
15,885,767 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm storing objects, in a List<t>. In my RemovePoolObject and GetPoolObject functions to work. But, I can't access the TestClass fields.

       #region ObjectPooler
       public class PooledObject<T>
       {
           public Func<T> ObjectInitializer { get; }

           public PooledObject(Func<T> objectInitializer) { ObjectInitializer = objectInitializer ?? throw new ArgumentNullException(nameof(objectInitializer)); }
       }

       public enum PoolAddMethod
       {
           None,
           SingleObject //Initialize Single Object
       }

       public class ObjectPooler<T>
       {
           public List<T> _deepEndObjects { get; set; }
           private PooledObject<T> _deepEndObject;

           public PoolAddMethod AddObjectMethod { get; set; }

           public ObjectPooler(PooledObject<T> pooledObject, PoolAddMethod addObjectMethod)
           {
               _deepEndObject = pooledObject ?? throw new ArgumentNullException(nameof(pooledObject));

               AddObjectMethod = addObjectMethod;

               _deepEndObjects = new List<T>();
           }

           public void AddPoolObject() { _deepEndObjects.Add(_deepEndObject.ObjectInitializer.Invoke()); }

           public void EmptyPool() { _deepEndObjects.Clear(); }

           public T GetPoolObject(string gGet = "")
           {
               //Return a object at given idx or in this case a given GUID

               //return _deepEndObjects.Find(x => x.g.ToString() == gGet);
               return default(T);
           }

           public void RemovePoolObject(string gRemove = "")
           {
               //Remove a object at given idx or in this case a given GUID

               //_deepEndObjects.Remove(_deepEndObjects.Find(x => x.g.ToString() == gRemove));
           }
       }
       #endregion

       public class TestClass
       {
           public Guid g = Guid.NewGuid(); //Just for testing. Real class would like an unique ID
       }

PooledObject<TestClass> _pooledObject;
       ObjectPooler<TestClass> objectPooler;

       public Form1()
       {
           InitializeComponent();

           _pooledObject = new PooledObject<TestClass>(() => ObjectAlloc<TestClass>.New());

           objectPooler = new ObjectPooler<TestClass>(_pooledObject, PoolAddMethod.SingleObject);
       }

       private void genbutton_Click(object sender, EventArgs e)
       {
           int iTag = Convert.ToInt32((sender as Control).Tag);

           switch (iTag)
           {
               case 0:
                   objectPooler.AddPoolObject();
                   break;
               case 1:
                   if (listView1.SelectedItems.Count > 0)
                   {
                       objectPooler.RemovePoolObject();
                       objectPooler._deepEndObjects.Remove(objectPooler._deepEndObjects.Find(x => x.g.ToString() == listView1.SelectedItems[0].Text));
                   }
                   break;
               case 2:
                   objectPooler.EmptyPool();
                   break;
               default:
                   break;
           }

           listView1.Clear();

           objectPooler._deepEndObjects.ForEach(x => listView1.Items.Add($"{x.g.ToString()}"));
       }


What I have tried:

_deepEndObjects.Remove(_deepEndObjects.Find(x => x.g.ToString() == gRemove));
Posted
Updated 9-Jun-18 5:07am

Use GetHashCode() of the underlying object to track your objects' "id's".
 
Share this answer
 
Comments
Member 13839622 8-Jun-18 20:35pm    
Ya ... That's a good idea. I might, use that. I'm using a GUID here, just for testing. What I'm after here, is how to to get each object out and use it or remove it.
[no name] 9-Jun-18 10:36am    
You don't have to resort to generics when dealing with "different objects"; i.e. List<object>, etc. works just fine for your apparent requirements.

If and when you actually need to know, THEN you get its type.
If you need to access properties or methods from your generic type parameter, the simplest option is to have your types implement an interface, and constrain the type parameter to types which implement that interface.

For example:
C#
public interface IObjectWithId
{
    Guid ObjectId { get; }
}

public class TestClass : IObjectWithId
{
    public Guid ObjectId { get; } = Guid.NewGuid();
}

public class ObjectPooler<T> where T : IObjectWithId
{
    ...
    
    public T GetPoolObject(Guid objectId)
    {
        return _deepEndObjects.Find(x => x.ObjectId == objectId);
    }
    
    public bool RemovePoolObject(Guid objectId)
    {
        int numberOfObjectsRemoved = _deepEndObjects.RemoveAll(x => x.ObjectId == objectId);
        return numberOfObjectsRemoved != 0;
    }
}


NB: Object pools are frequently called from multiple threads at the same time. Your code is currently not thread-safe. If you call it from multiple threads, you will end up corrupting the state of the pool.

If that's a problem, you might want to look at using a concurrent collection[^]. For example:
How to: Create an Object Pool by Using a ConcurrentBag | Microsoft Docs[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900