2012-02-10 3 views
1

Я пытаюсь создать пул объектов, который будет иметь объекты разных типов.Как создать пул объектов для разных типов?

Будет ли возможно, если я передал строку как ps параметр RetriveFunction(); он должен rturn новый объект типа string или feth его из пула?

строка будет содержать название типа.

Например;

Object RetriveFromPool(string typename) 
    { 
      if()//object does not present 
      { 
       //return new object of typename 
      } 
      else 
      { 
       //feth it from pool 
      } 
    } 

можно ли?

ответ

2

Да, это возможно. Словарь представляет собой удобный способ для хранения пар ключей значения с O (1) поиском и Activator способен инстанцированием типа, известным только во время выполнения:

private IDictionary<string, object> _objectPool; 
object RetriveFromPool(string typeName) 
{  
    if(_objectPool.ContainsKey(typeName)) 
    { 
     return _objectPool[typename]; // return from the pool 
    } 
    return Activator.CreateInstance(Type.GetType(typeName)); // Try to create a new object using the default constructor 
} 

В качестве альтернативного однако (для обеспечения компиляции проверки типов времени) вы возможно, пожелает использовать дженерики для достижения этой цели:

private IDictionary<Type, object> _objectPool; 
public T RetrieveFromPool<T>() where T : new() 
{ 
    Type type = typeof(T); 
    return _objectPool.ContainsKey(type) ? (T)_objectPool[type] : new T(); 
} 

// Update - add a couple of templates for add methods: 

public void AddToPool<T>() where T : new 
{ 
    _objectPool[typeof(T)] = new T(); 
} 

public void AddToPool<T>(T poolObject) where T : new 
{ 
    _objectPool[typeof(T)] = poolObject; 
} 
+0

Можно ли избежать отражения? –

+0

@NIleshLanke См. Обновление. –

+0

@ rich.okelly Дарн, ты продолжаешь красть мои идеи! Мы думаем точно на одной странице. Однако у вас есть ошибка в вашем первом образце. Вы никогда не храните вновь созданный объект. На самом же деле это второй. – Zenexer

0

Если типы известны в compiletime, вы бы лучше с обобщениями:

IDictionary<Type, object> Pool = new Dictionary<Type, object>(); 

T RetrieveFromPool<T>() 
    where T : new() 
{ 
    if (Pool.ContainsKey(typeof(T))) 
    { 
     return Pool[typeof(T)]; 
    } 

    return Pool[typeof(T)] = new T(); 
} 

Вот самый безопасный способ использования струн/отражений, которые я могу придумать:

IDictionary<string, object> Pool = new Dictionary<string, object>(); 

object RetrieveFromPool(string typeName) 
{ 
    if (Pool.ContainsKey(typeName)) 
    { 
     return Pool[typeName]; 
    } 

    Type type = Type.GetType(typeName); 
    if (type == null) 
    { 
     return null; 
    } 

    ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes); 
    if (ctor == null) 
    { 
     return null; 
    } 

    object obj = ctor.Invoke(new object[0]); 
    Pool[typeName] = obj; 
    return obj; 
} 
Смежные вопросы