닷넷(.Net)에서 열거형(Enum)은 자체로도 클래스(Class)와 비슷한 역할을 수행합니다.
그런데 열거형의 문제는 열거형 멤버를 직접 다루려면 손이 많이 간다는 것입니다.
우리는 객체지향(Object-Oriented Programming, OOP)을 통해 이런 손이 많이 가는 작업은 클래스를 만들어 캡슐화하여 처리하라고 배웠습니다.
그러니 열거형을 클래스로 변환해 봅시다.
(Enum to Class)
닷넷에서 열거형은 구성이 잘되어 있어 형 변환도 쉽습니다.
그러니 이러한 작업을 해주는 클래스를 만들면 됩니다!
상황에 따라서 구조체(struct)를 사용해도 되지만 형 변환과정에서 무언가 더 필요할 수 있으니 모델로 만들어 줍니다.
/// <summary> /// 열거형 멤버의 정보를 검색하기 쉽게 저장하는 모델 /// </summary> public class EnumMemberModel { /// <summary> /// 지정된 열겨헝 멤버 /// </summary> public Enum Type { get; private set; } /// <summary> /// 지정된 열겨헝 멤버의 이름 /// </summary> public string Name { get; private set; } /// <summary> /// 지정된 열겨헝 멤버의 인덱스 /// </summary> public int Index { get; private set; } /// <summary> /// 사용할 열거형 멤버를 오브젝트(object)형태로 처리합니다. /// </summary> /// <param name="objData"></param> public EnumMemberModel(object objData) { SetData(objData as Enum); } /// <summary> /// 사용할 열거형 멤버를 지정합니다. /// </summary> /// <param name="typeData"></param> public EnumMemberModel(Enum typeData) { SetData(typeData); } /// <summary> /// 필요한 데이터를 기록 합니다. /// </summary> /// <param name="typeData"></param> private void SetData(Enum typeData) { this.Type = typeData; this.Index = this.Type.GetHashCode(); this.Name = this.Type.ToString(); } }
여기서 'Enum'을 주의해야 합니다.
'Enum'는 두 가지 용도로 사용이 가능한 데
첫 번째는 위와 같이 '열거형 멤버'로 사용할 수 있고,
두 번째는 '열거형' 자체를 저장하기 위한 용도로 사용할 수 있습니다.
생성자를 통해 '열거형 멤버'를 전달하면 전달된 열거형 멤버를 형 변환하여 저장합니다.
이제 위에서 만든 저장용 클래스를 이용하여 '열거형'을 배열로 만들어 관리하는 클래스를 만듭니다.
/// <summary> /// 열거형의 멤버를 분해하여 배열형태로 관리 해주는 클래스. /// </summary> public class EnumList { /// <summary> /// 지정된 열거형 /// </summary> public Enum EnumType { get; private set; } /// <summary> /// 분해한 열거형 멤버 데이터 /// </summary> public EnumMemberModel[] EnumMember { get; private set; } /// <summary> /// 지정된 열거형의 멤버 갯수 /// </summary> public int Count { get { return this.EnumMember.Length; } } /// <summary> /// 빈 개체를 생성함. /// </summary> public EnumList() { } /// <summary> /// 지정한 열거형 맴버를 분해하여 개체를 생성함. /// </summary> /// <param name="typeData"></param> public EnumList(Enum typeData) { this.EnumToClass(typeData); } /// <summary> /// 지정한 열거형 맴버를 분해하여 저장함 /// </summary> /// <param name="typeData"></param> public void EnumToClass(Enum typeData) { //원본 저장 this.EnumType = typeData; //들어온 열거형을 리스트로 변환한다. Array arrayTemp = Enum.GetValues(this.EnumType.GetType()); //맴버 갯수만큼 공간을 만들고 this.EnumMember = new EnumMemberModel[arrayTemp.Length]; //각 맴버를 입력한다. for (int i = 0; i < arrayTemp.Length; ++i) { this.EnumMember[i] = new EnumMemberModel(arrayTemp.GetValue(i)); } } /// <summary> /// 멤버중 지정한 이름이 있는지 찾습니다. /// </summary> /// <param name="sName"></param> /// <returns></returns> public EnumMemberModel FindEnumMember(string sName) { EnumMemberModel emReturn = null; List<EnumMemberModel> listEM = new List<EnumMemberModel>(); //검색한다. listEM = this.EnumMember.Where(member => member.Name == sName).ToList(); if (0 < listEM.Count) { //검색된 데이터가 있다면 //맨 첫번째 값을 저장 emReturn = listEM[0]; } return emReturn; } }
'EnumMember'클래스와 달리 'Enum'을 이용하여 열거형을 받아 처리하게 됩니다.
열거형을 'Enum'로 받아서 처리할 수 있다는 것만 안다면 주석만으로도 내용은 어렵지 않습니다.
이 클래스의 활용 방법을 위해 'FindEnumMember(string sName)'라는 함수를 만들어 보았습니다.
이제 사용을 해야 하는데 여기서 주의해야 할 것이 열거형을 전달할 때는 인스턴스를 만들어서 전달해야 합니다.
즉 생성할 때 'new'키워드를 사용해야 한다는 것이죠.
EnumList newEnum = new EnumList(new Test2());
이런 식으로 처리해야 합니다.
테스트용 함수를 아래와 같이 만듭니다.
private void SetListView(Enum typeData) { //열거형 지정 EnumList newEnum = new EnumList(typeData); //컨트롤을 지우고 listView1.Clear(); //리스트뷰 바인드 시작 listView1.BeginUpdate(); //뷰모드 listView1.View = View.Details; //열거형으로 컬럼 생성 for (int i = 0; i < newEnum.Count; ++i) { listView1.Columns.Add(newEnum.EnumMember[i].Name); } //아이템 추가 string[] sData = new string[newEnum.Count]; for (int i = 0; i < newEnum.Count; ++i) { sData[i] = newEnum.EnumMember[i].Index.ToString(); } listView1.Items.Add(new ListViewItem(sData)); //리스트뷰 바인드 완료 listView1.EndUpdate(); }
'ListView'컨트롤을 이용하여 완성된 데이터를 출력해 봅시다.
완성된 라이브러리 : github - dang-gun/DGUtility_DotNet/DGU_EnumToClass
테스트용 프로젝트 : github - dang-gun/DGUtility_DotNet/DGU_EnumToClass_Test
메뉴를 열거형으로 관리하면 여러 가지로 편합니다.
그런데 매번 변환하여 비교하는 것도 번거롭고 'Max' 멤버 만들어 쓰기도 번잡스럽고 해서 만들어 보았습니다.
이전 버전 :