닷넷(.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' 멤버 만들어 쓰기도 번잡스럽고 해서 만들어 보았습니다.
이전 버전 :