2009-04-08 5 views
0

나는이 신원 정보지도의 기초로이 ObjectPool 클래스를 사용했습니다. 그러나 유형의 모든 객체 목록을 가져와야합니다. 마태는이 있습니다일반 사전에서 값 목록을 가져 오는 방법

public IEnumerable<T> GetItems<T>() 
    { 
     Type myType = typeof(T); 

     if (!m_pool.ContainsKey(myType)) 
      return new T[0]; 

     return m_pool[myType].Values as IEnumerable<T>; 
    } 

을하지만, 내가 지금 같은 클라이언트로 변경 할 때 :

 pool.AddItem<Animal>(dog.ID, dog); 
     pool.AddItem<Vegetable>(carrot.Identifier, carrot); 
     pool.AddItem<Vegetable>(greenbean.Identifier, greenbean); 
     pool.AddItem<Mineral>(carbon.UniqueID, carbon); 

     Console.WriteLine("Dog is in the pool -- this statement is " + pool.ContainsKey<Animal>(dog.ID)); 

     IEnumerable<Vegetable> veggies = pool.GetItems<Vegetable>(); 
     foreach(Vegetable veg in veggies) 
      Console.WriteLine(string.Format("{0} - {1}", veg.Color, veg.IsTasty)); 

채소가 null입니다. m_pool [myType] .Values가 IEnumerable에 대한 캐스트를 지원하지 않는 것으로 보입니다.

나는 예를 들어, 몇 가지를 시도했다 :

 IDictionary<int, T> dic = (IDictionary<int, T>) m_pool[myType]; 
     ICollection<T> values = (ICollection<T>)dic.Values; 

그러나, 나는 항상 캐스팅 오류와 끝까지.

무엇이 누락 되었습니까?

답변

9

글쎄, 그 GetItems 방법은 결코Dictionary<int, object>.Values로 보는 것은 IEnumerable<T>하지 않는 Tobject이다 구현하지 않습니다 작동 할 것이다. 그 방법이 근본적으로 망가 졌음을 수치스럽게 - 오 일부 단위 테스트.

나는 라이센스를 확인하시기 바랍니다, 당신은 GetItems를 해결할 수 있는지, 그렇게 : 당신이 .NET 3.5을 사용하는 경우의

public IEnumerable<T> GetItems<T>() 
{ 
    Type myType = typeof(T); 

    IDictionary<int, object> dictionary; 

    if (!m_pool.TryGetValue(myType, out dictionary)) 
    { 
     return new T[0]; 
    } 

    return dictionary.Values.Cast<T>(); 
} 

가 (당신이 Cast을 얻을뿐만 아니라, using System.Linq이 필요합니다 확장 방법). .NET 2.0에 필요한 것이 있다면 알려주십시오.

+0

모든 장점' 새로운 T [0]'Enumerable.Empty ()'이상? 나는 단지 호기심에서 벗어나고있다. –

+0

정말 없습니다. 최대한 많은 코드를 재사용했습니다 :) (아마도 LINQ 이전에 쓰여졌을 것입니다.) –

+0

+1 .Cast 은 내가 찾고있는 코드입니다. –

0

나는 다음과 같은 ObjectPool을 사용 (코드 내 아닙니다 나는 방법 방금 추가 한 커플) (당신이 Console.WriteLine으로 logger.Info 교체 log4net 사용하지 않는 경우) 사용

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Collections.Specialized; 
using System.Reflection; 
using log4net; 
using log4net.Config; 


namespace DH 
{ 

    //DH - DataHolders 
    /// <summary> 
    /// This class models a storage structure for objects queriable by id 
    /// </summary> 
    public class ObjectPool 
    { 

     #region Props 
     private int totalCount; 
     public int TotalCount 
     { 
      get 
      { 
       return totalCount; 
      } 
     } 

     public int ID { get; set; } 


     #endregion Props 


     public ObjectPool() 
     { 
      m_pool = new Dictionary<Type, Dictionary<Int32, Object>>(); 
     } 


     private Dictionary<Type, Dictionary<Int32, Object>> m_pool; 

     public void AddItem<T> (Int32 pID, T value) 
     { 
      Type myType = typeof (T); 

      if (!m_pool.ContainsKey (myType)) 
      { 
       m_pool.Add (myType, new Dictionary<int, object>()); 
       m_pool[myType].Add (pID, value); 

       totalCount++; 
       return; 
      } 

      if (!m_pool[myType].ContainsKey (pID)) 
      { 
       m_pool[myType].Add (pID, value); 
       totalCount++; 
       return; 
      } 

      m_pool[myType][pID] = value; 
      totalCount++; 
      //Utils.Debugger.WriteIf("Adding 1 to pool count , pool count is " + this.totalCount); 
     } 


     public void AddItem<T> (T value) 
     { 
      Int32 pID = totalCount ; 
      Type myType = typeof (T); 

      if (!m_pool.ContainsKey (myType)) 
      { 
       m_pool.Add (myType, new Dictionary<int, object>()); 
       m_pool[myType].Add (pID, value); 

       totalCount++; 
       return; 
      } 

      if (!m_pool[myType].ContainsKey (pID)) 
      { 
       m_pool[myType].Add (pID, value); 
       totalCount++; 
       return; 
      } 

      m_pool[myType][pID] = value; 
      totalCount++; 
      //Utils.Debugger.WriteIf("Adding 1 to pool count , pool count is " + this.totalCount); 
     } 


     public bool RemoveItem<T> (Int32 pID) 
     { 
      Type myType = typeof (T); 

      if (!m_pool.ContainsKey (myType)) 
       return false; 

      if (!m_pool[myType].ContainsKey (pID)) 
       return false; 

      totalCount--; 
      return m_pool[myType].Remove (pID); 
     } 

     public bool ContainsKey<T> (Int32 pID) 
     { 
      Type myType = typeof (T); 

      if (!m_pool.ContainsKey (myType)) 
       return false; 

      if (!m_pool[myType].ContainsKey (pID)) 
       return false; 

      return m_pool[myType].ContainsKey (pID); 
     } 

     public IEnumerable<T> GetItems<T>() 
     { 
      Type myType = typeof (T); 

      if (!m_pool.ContainsKey (myType)) 
       return new T[0]; 

      return m_pool[myType].Values as IEnumerable<T>; 
     } 


     /// <summary> 
     /// Gets the item. 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="pID">The p ID.</param> 
     /// <returns></returns> 
     /// <exception cref="KeyNotFoundException"></exception> 
     public T GetItem<T> (Int32 pID) 
     { 
      // will throw KeyNotFoundException if either of the dictionaries 
      // does not hold the required key 
      return (T)m_pool[typeof (T)][pID]; 
     } 


     /// <summary> 
     /// 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="strPropMetaName"> the string representation of the </param> 
     /// <param name="strPropValue"></param> 
     /// <returns></returns> 
     public T GetItemByPropertyValue<T> (String strPropMetaName , String strPropValue) 
     { 
      Type myType = typeof (T); 

      for (int i = 0; i < this.TotalCount; i++) 
      { 
       if (!m_pool.ContainsKey (myType)) 
       { 
        return default (T); 
       } 
       else 
       { 
        if (this.ContainsKey<T> (i)) 
        { 
         //get an item object having the same type 
         T item = this.GetItem<T> (i); 

         //if the object has the same property -- check its value 
         MemberInfo[] members = myType.GetMembers(); 
         for (int j = 0; j < members.Length; j++) 
         { 
          logger.Info ("members[j].Name is " + members[j].Name); 
          //logger.Info (".MemberType.ToString() " + members[j].MemberType.ToString()); 
          //logger.Info ("members[j].GetType().ToString() " + members[j].GetType().ToString()); 
          //logger.Info (" members[j].ToString() is " + members[j].ToString()); 
          //logger.Info (" members[j].ToString() is " + members[j]); 


          if (members[j].Name.ToString().Equals (strPropMetaName)) 
          { 


           FieldInfo[] fi; 
           fi = myType.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 


           foreach (FieldInfo f in fi) 
           { 
            //logger.Info ("f.GetValue(obj) is " + f.GetValue (item)); 
            if (f.GetValue (item).ToString().Equals(strPropValue)) 
             return (T)m_pool[typeof (T)][i]; 
            else 
             continue ; 

           } //eof foreach        
          } 
          else 
           continue; 
         } //eof for j 

        } //eof if 
        else 
         continue; 
       } //eof else if m_pool.ContainsKey 
      } 
      return default (T); 
     } 


     private static readonly ILog logger = 
LogManager.GetLogger (typeof (DH.ObjectPool)); 

    } //eof class pool 

} //eof namespace 



namespace PoolSample 
{ 
    class Program 
    { 
     private static readonly ILog logger = 
LogManager.GetLogger (typeof (Program)); 

     public static DH.ObjectPool pool = new DH.ObjectPool(); 

     static void Main (string[] args) 
     { 
      DOMConfigurator.Configure(); //tis configures the logger 

      Animal dog = new Animal() { Name = "Fido", ID = 1 }; 
      Vegetable carrot = new Vegetable { Color = "Orange", Identifier = 2, IsTasty = true }; 
      Mineral carbon = new Mineral() { UniqueID = 3, IsPoisonousToAnimal = false , Name="some"}; 
      HolderForStrings hfs = new HolderForStrings() { ID = 4, Value = "user_name", MetaName = "meta_nam" }; 
      HolderForStrings hfs1 = new HolderForStrings() { ID = 5, Value = "user_name", MetaName = "hfs1" }; 
      Mineral carbon1 = new Mineral() { UniqueID = 3, IsPoisonousToAnimal = false, Name = "some1" }; 

      pool.AddItem (dog); 
      pool.AddItem (carrot); 
      pool.AddItem (hfs); 
      pool.AddItem (hfs1); 


      //pool.AddItem<Animal>(dog.ID, dog); 
      //pool.AddItem<Vegetable>(carrot.Identifier, carrot); 
      //pool.AddItem<Mineral> (carbon); 
      //pool.AddItem<HolderForStrings> (1, hfs); 



      //logger.Info("Dog is in the pool -- this statement is " + pool.ContainsKey<Animal>(dog.ID)); 
      //logger.Info("hfs is in the pool -- this statement is " + pool.ContainsKey<HolderForStrings>(hfs.ID)); 
      //logger.Info("The hfs value is from the poos is " + pool.GetItem<HolderForStrings>(4).Value); 


      //logger.Info("poo.GetItems is " + pool.GetItems<HolderForStrings>()); 
      #region while 
      //for (int i = 0; i < pool.Count -1 ; i++) 
      int i = 1; 
      do 
      { 
       try 
       { 
        logger.Info ("counting"); 
        logger.Info (" i is " + i.ToString()); 
        if (pool.ContainsKey<Animal> (i)) 
        { 
         logger.Info (" I see animal which is " + pool.GetItem<Animal> (i).Name); 
        } 

        if (pool.ContainsKey<Vegetable> (i)) 
        { 
         logger.Info (" I see Vegetable which is " + pool.GetItem<Vegetable> (i).Color); 
        } 


        if (pool.ContainsKey<Mineral> (i)) 
        { 
         logger.Info (" I see Mineral which is " + pool.GetItem<Mineral> (i).IsPoisonousToAnimal); 
        } 


        if (pool.ContainsKey<HolderForStrings> (i)) 
        { 
         logger.Info (" I see string which is " + pool.GetItem<HolderForStrings> (i).Value); 
        } 

        //logger.Info("pool.GetItem<HolderForStrings>(4).Value); is " + pool.GetItem<Object>(i).ToString()); 

        i = i + 1; 
       } 
       catch (KeyNotFoundException e) 
       { 
        continue; 
       } 

      } //eof for 
      while (i < pool.TotalCount); 
#endregion while 
      #region AddHolders 
      ////this is the success identifier 
      //HoldInt16 holdVerifier = new HoldInt16() 
      //{ 
      // ID=0 , 
      // MetaName = "ret", 
      // Value = 0 
      //}; 
      //pool.AddItem<HoldInt16>(holdVerifier.ID, holdVerifier); 

      //ListDictionary lidMetaName = pool.LidMetaName; 
      ////this is the message 
      //HoldString holdMsg = new HoldString(ref lidMetaName) 
      //{ 
      // ID=1, 
      // MetaName = "msg", 
      // Value = msg, 
      // Title = "title" 
      //}; 
      //pool.AddItem<HoldString>(holdMsg.ID, holdMsg); 


      //HoldString holdmmsg = new HoldString(ref lidMetaName) 
      //{ 
      // ID=2, 
      // MetaName = "mmsg", 
      // Value = "mmsg" , 
      // Title = "title" 
      //}; 
      #endregion AddHolders 


      //Utils.Debugger.DebugListDictionary(ref msg, "domainName", ref lidMetaName); 

      //get the value be metaName 

      logger.Info ("I queried the pool by property with meta Value and value user_name "); 

      HolderForStrings HolderForStrings = pool.GetItemByPropertyValue<HolderForStrings> ("MetaName", "hfs1"); 
      //logger.Info ("object dump" + Utils.Log.ObjDumper.DumpObject (HolderForStrings)); 
      logger.Info ("I found the following value for property with the name \"Name\" "); 
      logger.Info (HolderForStrings.MetaName); 

      Console.ReadLine(); 







     } //eof Main 

    } //eof class 

    public class Animal 
    { 
     public Int32 ID { get; set; } 
     public String Name { get; set; } 
    } 

    public class HolderForStrings 
    { 
     public Int32 ID { get; set; } 
     public String Value { get; set; } 
     public String MetaName { get; set; } 
     Type ObjType = typeof (string); 
     public Int32 Size { get; set; } 
     public bool IsOptional { get; set; } 
     public bool IsPrimaryKey { get; set; } 

    } //eof class 


    public class Vegetable 
    { 
     public Int32 Identifier { get; set; } 
     public String Color { get; set; } 
     public Boolean IsTasty { get; set; } 
    } 

    public class Mineral 
    { 
     public Int32 UniqueID { get; set; } 
     public Boolean IsPoisonousToAnimal { get; set; } 
     public String Name { get; set; } 
    } 

    #region classObjectPool 
    //public class ObjectPool 
    //{ 
    // public int Count 
    // { 
    // get { return m_pool.Count; } 
    // } 

    // public ObjectPool() 
    // { 
    // m_pool = new Dictionary<Type, Dictionary<Int32, Object>>(); 
    // } 

    // private Dictionary<Type, Dictionary<Int32, Object>> m_pool; 

    // public void AddItem<T> (Int32 pID, T value) 
    // { 
    // Type myType = typeof (T); 

    // if (!m_pool.ContainsKey (myType)) 
    // { 
    //  m_pool.Add (myType, new Dictionary<int, object>()); 
    //  m_pool[myType].Add (pID, value); 
    //  return; 
    // } 

    // if (!m_pool[myType].ContainsKey (pID)) 
    // { 
    //  m_pool[myType].Add (pID, value); 
    //  return; 
    // } 

    // m_pool[myType][pID] = value; 
    // } 

    // public bool RemoveItem<T> (Int32 pID) 
    // { 
    // Type myType = typeof (T); 

    // if (!m_pool.ContainsKey (myType)) 
    //  return false; 

    // if (!m_pool[myType].ContainsKey (pID)) 
    //  return false; 

    // return m_pool[myType].Remove (pID); 
    // } 

    // public bool ContainsKey<T> (Int32 pID) 
    // { 
    // Type myType = typeof (T); 

    // if (!m_pool.ContainsKey (myType)) 
    //  return false; 

    // if (!m_pool[myType].ContainsKey (pID)) 
    //  return false; 

    // return m_pool[myType].ContainsKey (pID); 
    // } 

    // public IEnumerable<T> GetItems<T>() 
    // { 
    // Type myType = typeof (T); 

    // if (!m_pool.ContainsKey (myType)) 
    //  return new T[0]; 

    // return m_pool[myType].Values as IEnumerable<T>; 
    // } 

    // /// <summary> 
    // /// Gets the item. 
    // /// </summary> 
    // /// <typeparam name="T"></typeparam> 
    // /// <param name="pID">The p ID.</param> 
    // /// <returns></returns> 
    // /// <exception cref="KeyNotFoundException"></exception> 
    // public T GetItem<T> (Int32 pID) 
    // { 
    // // will throw KeyNotFoundException if either of the dictionaries 
    // // does not hold the required key 
    // return (T)m_pool[typeof (T)][pID]; 
    // } 

    //} //eof pool 
    #endregion 

    public enum EnumType : byte 
    { 
     String, 
     Int32, 
     Boolean 
    } 
} //eof program 
관련 문제