| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | using System;using System.Collections;using System.Linq;using System.Text;using System.Reflection;namespace IControls_ExcelVerify{    /// 2012. 5.25 최종 판단    /// 해쉬테이블과 리스트를 혼용하기로 함    ///    /// HashTable 의 경우     /// 1. 키가 존재하므로 자료 중복 체크 가능하다.     /// 2. 삭제가 쉽다. (데이타 타입에 상관없이 삭제가능하다)    /// 3. 해쉬테이블안에 해쉬테이블이 있을 경우 접근이 힘들다 (데이타베이스의 쿼리만큼의 작업이 소요된다)    /// 4. 기존프로젝트와의 함수 및 변수 재사용성이 떨어진다    /// 5. 키값을 기준으로 하기 때문에 데이타베이스와 호환성은 우수하다.    ///      /// 리스트 의경우    /// 1. 중복 체크는 불가능하다 (리스트에 클래스 단위로 저장하는 경우)    /// 2. 삭제가 쉽지않다 (단일 자료형태가 들어가는 경우는 쉽지만 클래스 형태로 들어가는 리스트의 아이템을 추출하는것도 어렵고 리스트 검색도중 리스트가 삭제될수는 없다)    /// 3. 리스트안에 리스트가 있을 경우 접근이 쉽다 (단 키값으로 접근하지 못하기 때문에 부하가 걸릴 수가 있다)    /// (키를 이용해서 찾지 않아도 되므로 접근성은 유연하다 (ACU 클래스안의 DOOR 클래스가 존재하는 경우 사용여부를 판단하기가 쉽다)    /// 4. 재사용 가능하다.    ///      ///     /// 제일 좋은 방법은 공용 함수 파라미터에 클래스 타입 자체를 전달해서 받은 함수쪽에서 리플렉션과 어트리뷰트를 사용하는것인데     /// MSDN 예제에서도 결국은 클래스 타입 이름은 알수 있어도 그 자체를 Runtime 상에서 메모리에 할당하는 것은 불가능하다.      /// (제일 큰 문제가 바로 HashTable 의 경우 의 3번 문제이다. 접근성이 해결되지 않는 것이 너무나 큰 문제이므로 해쉬테이블을 사용이 힘듬    ///     ///     /// 결국 다음과 같이 사용한다    /// 1. 기본적인 자료는 해쉬테이블에 저장한다     /// 2. 해쉬테이블의 키값은 따로 리스트로 관리한다    /// 3. 키값으로 다이렉트로 접근할 수 있도록 구현하며 예제는 아래와 같다     /// 4. 해쉬테이블을 관리하는 키리스트는 항상 싱크가 맞도록 한다. (추가 : 해쉬테이블 추가 -> 키리스트에 추가, 삭제 : 해쉬테이블 제거 -> 키리스트 삭제    ///    /// 결론, 기존의 함수 사용법에 크게 벗어나지도 않으며 해쉬 테이블의 장점도 살릴수 있으며 속도도 빠르다. 특히 데이타베이스와 호환성은 충분히 살릴수 있다.    // 예시. ACU 해쉬테이블에서 DOOR 포트 사용여부를 조회하는 기능    //    // int a=0;// 원하는 값을 찾으면 카운트 증가    // ACU 키리스트만큼 돌린다        //foreach (string ACU_KEY in _Data.List_ACU_KEY)    //{    //    // 키에 있는 값을 토대로 접근한다    //    if(((_DEVICE_ACU)_Data.Hash_ACU[ACU_KEY]).ACU_LAN_IP =="61.33.215.151")    //    {    //        // 찾았던 ACU 해쉬테이블의 Door 키리스트만큼 돌린다    //        foreach (string DR_KEY in ((_DEVICE_ACU)_Data.Hash_ACU[ACU_KEY]).List_DR_KEY)    //        {    //            if (((_DEVICE_DOOR)((_DEVICE_ACU)_Data.Hash_ACU[ACU_KEY]).Hash_DR[DR_KEY]).PORT_ENABLE == true)    //                // 원하는 값을 찾았다    //                a++;    //        }    //    }    //}    //int b = a;    //b++;    // 해쉬테이블 생성,접근,삭제 는 여기에서 공용으로 처리할 수 있도록 한다        public static class _Hash    {        // 해쉬테이블에 추가         // 경고! 키값이 항상 ToString() 형태로 들어가므로 주의 요망        public static bool Add(Hashtable hashtable, object key, object value)        {            try            {                // 키 중복인지 확인한다                if (hashtable.ContainsKey(key) == false)                {                    hashtable.Add(key.ToString(), value);                    return true;                }                else                {                    //_Popup.Create(Popup_Type.Confirm, Popup_Style.Normal,_Text.Warnning, 250,150,_Text.OverLapKey,0);                    return false;                }            }            catch  // (Exception e)            {                // LOG                                //_Event.DebugView_SendMessage_Write(e.ToString());                return false;            }              }        // 해쉬테이블 가져오기                ///        /// 직접 엑세스하여 구하는 방법도 있다        ///                 // 예시         // hash 라는 해쉬테이블이 존재하고 그 해쉬테이블은 _MAIN 클래스 형태의 값들이 들어가있다        // 키값이 10인 경우 데이터를 가져오는 경우        // 즉, _MAIN 이라는 클래스의 a라는 변수의 값을 구하려면 아래와 같다        // ((_MAIN)hash["10"]).a;                // 키를 이용해서 데이터를 통째로 가져오기          public static object GetData_ByKey(Hashtable hashtable, object key)        {            foreach (DictionaryEntry d in hashtable)            {                if (d.Key.ToString() ==  key.ToString())                    return d.Value;            }            return null;        }        // 키값을 리스트 형태로 가져오는 방법        public static ArrayList GetKeyList_ByKey(Hashtable hashtable)        {            ArrayList result = new ArrayList();            foreach (DictionaryEntry d in hashtable)            {                // 키값은 string 형태로 가져온다                result.Add(d.Key.ToString());            }            return result;        }        ///        /// 해쉬테이블 삭제하기        ///                // 해쉬테이블에서 키로 데이타 삭제 (키는 ArrayList 로 받음)        public static void DelData_ByKey(Hashtable hashtable, ArrayList keyList)        {               foreach (object key in keyList)            {                hashtable.Remove(key.ToString());                                }        }                // 해쉬테이블에서 키로 데이타 삭제 (키는 StringList 로 받음) -> "test1" or "test1;test2"        public static void DelData_ByKey(Hashtable hashtable, string keyList)        {            string[] StringList = _Convert.String_to_ArrayString(keyList);            foreach (string key in StringList)            {                hashtable.Remove(key);            }        }        //// 해쉬테이블에서 키로 데이타 추출 (클래스를 아는 경우를 대비함 일단 미사용)        //public static object GetData_ByKey(Hashtable hashtable, System.Type t, object key)        //{        //    // reflection        //    // C#에는 사용자 지정 특성을 사용하여 정의된 정보를 검색할 수 있는 리플렉션 시스템이 있습니다.         //    // 중요한 메서드는 GetCustomAttributes로, 이 메서드는 런타임에 소스 코드 특성에 해당하는 개체 배열을 반환합니다.        //    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);        //    foreach (System.Attribute attr in attrs)        //    {        //        // is : 지정된 형식과 개체가 호환되는지 검사합니다        //        // 식이 항상 true이거나 항상 false인 것으로 알려져 있는 경우 is 키워드는 컴파일 타임 경고를 발생시키지만 런타임에는 일반적으로 형식 호환성을 확인합니다.        //        // is 연산자는 오버로드되지 않습니다.        //        // is 연산자는 참조 변환, boxing 변환 및 unboxing 변환만 고려하고 사용자 정의 변환 같은 다른 변환은 고려되지 않습니다.        //        if (attr is _MAIN)        //        {        //            return ((_MAIN)hashtable[key.ToString()]);        //        }        //    }        //    return null;        //}    }}
 |