C#

[C#]인덱서 사용 방법

DevStory 2022. 1. 17.

인덱서란?

인덱서(Indexers)는 클래스의 멤버로 클래스의 값을 배열처럼 접근할 수 있도록 해주는 문법입니다.

 

이번 포스팅에서는 인덱서 사용 방법을 소개합니다.

 


인덱서를 사용하지 않는 경우

다음 예제처럼 배열은 인덱스를 사용하여 해당 위치의 값을 접근할 수 있습니다.

class Program
{
    static void Main(string[] args)
    {
        int[] numArray = { 1, 2, 3, 4 };

        Console.WriteLine("0번째 인덱스의 값: " + numArray[0]);
        Console.WriteLine("2번째 인덱스의 값: " + numArray[2]);
    }
}

실행 결과

 

다음은 클래스 인스턴스에서 객체를 배열처럼 사용하는 경우입니다.

public class Person
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }

    public override string ToString()
    {
        return "Name: " + Name + " / Gender: " + Gender + " / Age: " + Age + " / Email: " + Email;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person() {
            Name="Tom", 
            Gender="Male", 
            Age= 20, 
            Email="Tom@Test.com" 
        };

        Console.WriteLine("Name: " + person[0]);
        Console.WriteLine("Gender: " + person[1]);
        Console.WriteLine("Age: " + person[2]);
        Console.WriteLine("Email: " + person[3]);
    }
}

실행 결과

배열은 .Net 프레임워크에서 정의된 클래스이며 배열의 값을 인덱스를 사용하여 접근할 수 있도록 구현되어 있습니다. 하지만, Person 클래스는 사용자(혹은 개발자)가 정의한 클래스이며 인덱서 기능이 없으므로 배열처럼 사용하면 오류가 발생합니다.

 

클래스를 배열처럼 사용하기 위해서는 클래스에 인덱서를 정의해야 합니다. 다음은 클래스에서 인덱서를 정의하는 방법입니다.


인덱서 정의 방법

다음은 인덱서 정의 구문입니다.

[한정자] 타입 this [int형 인덱스 또는 string명]
{
    get // get 접근자 
    {
    }
    set // set 접근자
    {
    }
}
  • 한정자: public, private, protected 등 접근 한정자를 설정합니다.
  • 타입: 인덱서 반환 타입을 정의합니다. Person 클래스에는 int, string 타입의 멤버 변수가 존재하므로 Object 타입으로 정의합니다.
  • this: 현재 클래스에 대해 인덱서를 정의하고 있음을 나타냅니다.
  • int형 인덱스 또는 string명: 인덱스 위치를 int형 인덱스로 접근할 것인지 또는 string명으로 접근할 것인지 설정합니다.

다음은 Person 클래스에 인덱스를 정의하는 예제입니다. 인덱스 위치를 int형 인덱스로 접근하도록 합니다.

public class Person
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }

    public Object this [int index]
    {
        get
        {
            if (index == 0)
                return Name;
            else if (index == 1)
                return Gender;
            else if (index == 2)
                return Age;
            else if (index == 3)
                return Email;
            else
                return null;
        }
        set
        {
            if (index == 0)
                Name = value.ToString();
            else if (index == 1)
                Gender = value.ToString();
            else if (index == 2)
                Age = Convert.ToInt32(value);
            else if (index == 3)
                Email = value.ToString();
        }
    }

    public override string ToString()
    {
        return "Name: " + Name + " / Gender: " + Gender + " / Age: " + Age + " / Email: " + Email;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person() {
            Name="Tom", 
            Gender="Male", 
            Age= 20, 
            Email="Tom@Test.com" 
        };

        Console.WriteLine("Name: " + person[0]);
        Console.WriteLine("Gender: " + person[1]);
        Console.WriteLine("Age: " + person[2]);
        Console.WriteLine("Email: " + person[3]);
    }
}

실행 결과

 

인덱스 위치를 정수형 인덱스로 접근하는 방식의 단점은 클래스의 속성이 많아지면, 인덱스 위치와 매핑되는 속성을 기억하기가 어렵다는 문제가 존재합니다. 이러한 경우 정수형 인덱스가 아닌 속성 이름을 사용할 수 있습니다.

 

다음은 정수형 인덱스를 문자열 이름으로 변경한 예제입니다. 실행 결과는 동일합니다.

public class Person
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }

    public Object this [int index]
    {
        get
        {
            if (indexName == "Name")
                return Name;
            else if (indexName == "Gender")
                return Gender;
            else if (indexName == "Age")
                return Age;
            else if (indexName == "Email")
                return Email;
            else
                return null;
        }
        set
        {
            if (indexName == "Name")
                Name = value.ToString();
            else if (indexName == "Gender")
                Gender = value.ToString();
            else if (indexName == "Age")
                Age = Convert.ToInt32(value);
            else if (indexName == "Email")
                Email = value.ToString();
        }
    }

    public override string ToString()
    {
        return "Name: " + Name + " / Gender: " + Gender + " / Age: " + Age + " / Email: " + Email;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person() {
            Name="Tom", 
            Gender="Male", 
            Age= 20, 
            Email="Tom@Test.com" 
        };

        Console.WriteLine("Name: " + person["Name"]);
        Console.WriteLine("Gender: " + person["Gender"]);
        Console.WriteLine("Age: " + person["Age"]);
        Console.WriteLine("Email: " + person["Email"]);
    }
}

인덱스 위치를 문자열 이름으로 접근하는 방식도 단점이 존재하는데, 대소문자 구분을 한다는 것입니다. 그러므로 ToLower() 또는 ToUpper() 함수를 사용하여 대소문자를 구분하지 않도록 합니다.

public class Person
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }

    public Object this [int index]
    {
        get
        {
            if (indexName.ToUpper() == "NAME")
                return Name;
            else if (indexName.ToUpper() == "GENDER")
                return Gender;
            else if (indexName.ToUpper() == "AGE")
                return Age;
            else if (indexName.ToUpper() == "EMAIL")
                return Email;
            else
                return null;
        }
        set
        {
            if (indexName.ToUpper() == "NAME")
                Name = value.ToString();
            else if (indexName.ToUpper() == "GENDER")
                Gender = value.ToString();
            else if (indexName.ToUpper() == "AGE")
                Age = Convert.ToInt32(value);
            else if (indexName.ToUpper() == "EMAIL")
                Email = value.ToString();
        }
    }

    public override string ToString()
    {
        return "Name: " + Name + " / Gender: " + Gender + " / Age: " + Age + " / Email: " + Email;
    }
}
반응형

댓글