Home Full Site
.NET Reflection을 이용한 클래스 객체 생성

클래스 타입을 알 때 .NET Reflection을 이용해서 해당 클래스의 객체를 생성할 수 있다. 이는 컴파일시에 직접 new를 사용하는 방식이 아니라, 클래스 타입명을 문자열로 받아들여 런타임시에 해당 클래스의 객체를 생성할 수 있는 것을 뜻한다. 또한, 어떤 객체를 받아들여 해당 타입을 얻은 후에 (ex: obj.GetType()), 이 타입의 또 다른 객체를 생성하는 것도 가능하다. 아래의 예제는 해당 Customer라는 클래스명을 사용하여 런타임시에 해당 객체를 생성하는 예이다. Type.GetType()을 이용하여 해당 타입을 알아내고 (주: 클래스명 앞에 네임스페이스를 붙여야 한다), 이어 Activator의 CreateInstance()를 사용하여 실제 클래스 객체를 생성한다.

예제

namespace MyNamespace
{
    using System;
    using System.Diagnostics;

    public class Class1
    {
        public void Run()
        {
            // 네임스페이스와 클래스명 함께
            Type customerType = Type.GetType("MyNamespace.Customer");

            // Type으로부터 클래스 객체 생성
            object obj = Activator.CreateInstance(customerType);

            // 생성된 객체 사용예
            string name = ((Customer)obj).Name;
            Debug.WriteLine(name);  // No name
        }
    }

    public class Customer
    {
        public Customer()
        {
            this.Name = "No name";
        }
        public int Id { get; set; }
        public string Name { get; set; }
    }
}




Generic 타입으로부터 객체 생성

클래스 타입이 확정되지 않은 Generic Type인 경우에는 (ex: MyFilter<T>) 파라미터 T가 정해지지 않으면 Activator로 객체를 생성할 수 없다. 그것은 Generic Type 자체로는 클래스가 되지 못하기 때문인데, 이 경우 먼저 Generic의 T 파라미터 타입을 GetGenericArguments()를 써서 알아낸 후, MakeGenericType(T)을 사용하여 구체적인 클래스를 만들어야 한다. 아래 예제는 MyFilter라는 Generic 타입이 object로 Run()함수에 전달되었을 때, T 파라미터를 알아내고 Generic으로부터 객체를 생성하는 예를 보여주고 있다.

예제

using System;
using System.Collections.Generic;
using System.Diagnostics;

public class Class2
{
    public Class2()
    {
        MyFilter<int> filter = new MyFilter<int>();
        Run(filter);
    }

    public void Run(object filter)
    {
        // Type명 비교
        if (filter.GetType().Name == typeof(MyFilter<>).Name)
        {
            // Generic의 T 파라미터 타입 가져오기 : int
            Type genArgType = filter.GetType().GetGenericArguments()[0];

            // MyFilter<>에 int를 적용하여 실제 타입 확정
            Type actualType = typeof(MyFilter<>).MakeGenericType(genArgType);

            // 실제 타입으로부터 객체 생성
            object obj = Activator.CreateInstance(actualType, true);

            Debug.WriteLine(obj.GetType().Name); //MyFilter`1
        }
    }
}

public class MyFilter<T>  where T : struct
{
    private List<T> _elements;        

    public MyFilter()
    {
        _elements = new List<T>();
    }

    public MyFilter(List<T> elements)
    {
        _elements = elements;
    }
}




© csharpstudy.com