문제

다른 클래스의 유형에 따라 파생 클래스를 반환하려는 아래 코드를 보유하는 더 우아한 방법은 무엇입니까?

            if (option_ is Rectangle)
            {
                modelInputs = new Foo();
            }
            else if (option_ is Circle)
            {
                modelInputs = new Bar();
            }
            else if (option_ is Triangle)
            {
                modelInputs = new Bar2();
            }
도움이 되었습니까?

해결책

사각형, 원 및 삼각형을 구현해야합니다.

interface IHasModelInput
{
    IModelInput GetModelInput();
}

그런 다음 할 수 있습니다

IModelInput modelInputs = option_.GetModelInput();

다른 팁

내 의견 : 당신의 "부적절한"방법은 괜찮습니다. 간단하고 읽기 쉬우 며 작업을 수행합니다.

직사각형, 원 및 삼각형을 사용하면 필요한 공장 기능을 구현합니다. IHASMODELINPUT 작동하지만 디자인 비용이 있습니다. 이제이 클래스 세트를 Imodelinput 클래스 세트 (Foo, Bar 및 Bar2)와 결합했습니다. 그들은 완전히 다른 두 개의 라이브러리에있을 수 있으며 아마도 서로에 대해 알지 못할 수도 있습니다.

더 복잡한 방법은 다음과 같습니다. 런타임에 공장 논리를 구성 할 수 있다는 이점을 제공합니다.

    public static class FactoryMethod<T>  where T : IModelInput, new()
    {
        public static IModelInput Create()
        {
            return new T();
        }
    }

    delegate IModelInput ModelInputCreateFunction();

    IModelInput CreateIModelInput(object item)
    {

        Dictionary<Type, ModelInputCreateFunction> factory = new Dictionary<Type, ModelInputCreateFunction>();


        factory.Add(typeof(Rectangle), FactoryMethod<Foo>.Create);
        factory.Add(typeof(Circle),    FactoryMethod<Bar>.Create);
        // Add more type mappings here




        IModelInput modelInput;
        foreach (Type t in factory.Keys)
        {
            if ( item.GetType().IsSubclassOf(t) || item.GetType().Equals(t))
            {
                modelInput = factory[t].Invoke();
                break;
            }
        }
        return modelInput;
    }

그런 다음 질문을하십시오. 어느 쪽을 읽으시겠습니까?

입력 및 출력을 해시 테이블에 넣거나 생성 한 각 클래스 내에 각 클래스를 생성 한 다음 Activator.createInstance를 사용하여 공장을 수행하는 유형을 저장할 수 있습니다. ':

Hashtable ht = new Hashtable();
ht.Add(typeof(Rectangle), typeof(Bar));
ht.Add(typeof(Square), typeof(Bar2));

modelInputs = Activator.CreateInstance(ht[option.GetType()]);

어느 쪽이든, Activator.createInstance는 .NET에서 공장을 작동시키는 매우 멋진 방법입니다. 내가 현명하게 준 힘을 즐기고 아들을 사용하십시오.

허용 된 경우 유형을 "Option_"와 연결 한 다음 인스턴스 만 만들 수 있습니다.

나는 일반적으로 런타임에 문자열을 유형으로 변환하려면 이와 같은 공장 메소드를 사용합니다. 문자열을 유형에 매핑하는 사전을 사용합니다.

최근 프로젝트에서 나와 같이 :

public class TaskFactory
{
    private Dictionary<String, Type> _taskTypes = new Dictionary<String, Type>();

    public TaskFactory()
    {
        // Preload the Task Types into a dictionary so we can look them up later
        foreach (Type type in typeof(TaskFactory).Assembly.GetTypes())
        {
            if (type.IsSubclassOf(typeof(CCTask)))
            {
                _taskTypes[type.Name.ToLower()] = type;
            }
        }
    }

    public CCTask CreateTask(XmlElement task)
    {
        if (task != null)
        {
            string taskName = task.Name;
            taskName =  taskName.ToLower() + "task";

            // If the Type information is in our Dictionary, instantiate a new instance of that task
            Type taskType;
            if (_taskTypes.TryGetValue(taskName, out taskType))
            {
                return (CCTask)Activator.CreateInstance(taskType, task);
            }
            else
            {
                throw new ArgumentException("Unrecognized Task:" + task.Name);
            }                               
        }
        else
        {
            return null;
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top