문제

내가 만든 추상 클래스에서 상속된 클래스 컬렉션이 있습니다.내 추상 클래스의 구체적인 구현 인스턴스를 생성하기 위한 팩토리로 추상 클래스를 사용하고 싶습니다.

상위 클래스를 제외한 모든 코드에서 생성자를 숨길 수 있는 방법이 있습니까?

나는 기본적으로 이것을하고 싶다

public abstract class AbstractClass
{
    public static AbstractClass MakeAbstractClass(string args)
    {
        if (args == "a")
            return new ConcreteClassA();
        if (args == "b")
            return new ConcreteClassB();
    }
}

public class ConcreteClassA : AbstractClass
{
}

public class ConcreteClassB : AbstractClass
{
}

하지만 나는 누구도 2개의 구체적인 클래스를 직접 인스턴스화하지 못하도록 하고 싶습니다.MakeAbstractClass() 메서드만 기본 클래스를 인스턴스화할 수 있는지 확인하고 싶습니다.이를 수행할 수 있는 방법이 있습니까?

업데이트
Abstract 클래스 외부에서 ConcreteClassA 또는 B의 특정 메서드에 액세스할 필요가 없습니다.내 Abstract 클래스가 제공하는 공개 메서드만 필요합니다.콘크리트 클래스가 인스턴스화되는 것을 막을 필요는 없습니다. 새로운 공용 인터페이스를 제공하지 않고 추상 클래스 내부의 매우 구체적인 일부 항목을 다르게 구현하기 때문에 이를 피하려고 합니다.

나에게 가장 간단한 해결책은 samjudson이 언급한 것처럼 어린이 수업 만들기.그러나 나는 이것을 피하고 싶습니다. 왜냐하면 그것이 내 추상 클래스의 파일을 내가 원하는 것보다 훨씬 더 크게 만들 것이기 ​​때문입니다.차라리 정리를 위해 몇 개의 파일로 클래스를 분할하는 것이 좋습니다.

이 문제에 대한 쉬운 해결책은 없는 것 같아요...

도움이 되었습니까?

해결책

다음과 같이 하위 클래스를 하위 클래스로 만들 수 있습니다.

public abstract class AbstractClass
{
    public static AbstractClass MakeAbstractClass(string args)
    {
        if (args == "a")
            return new ConcreteClassA();
        if (args == "b")
            return new ConcreteClassB();
    }

    private class ConcreteClassA : AbstractClass
    {
    }

    private class ConcreteClassB : AbstractClass
    {
    }
}

@Vaibhav 이는 실제로 클래스도 숨겨져 있음을 의미합니다.그러나 이것이 내가 아는 한 생성자를 완전히 숨기는 유일한 방법입니다.

편집하다:다른 사람들이 언급했듯이 Reflection을 사용하여 동일한 작업을 수행할 수 있습니다. 이는 실제로 원하는 경우에 더 가까울 수 있습니다. 예를 들어 위의 메서드는 Abstract 클래스와 동일한 파일 내에 있는 구체적인 클래스에 응답합니다. 별로 편리하지 않습니다.이 방법은 좋은 '해킹'이며 구체적인 클래스의 수와 복잡성이 낮으면 좋습니다.

다른 팁

나에게 가장 간단한 해결책은 Samjudson이 언급했듯이 어린이 수업을 만드는 것입니다.그러나 나는 이것을 피하고 싶습니다. 내 추상 클래스의 파일을 원하는 것보다 훨씬 더 크게 만들기 때문입니다.오히려 클래스가 조직을 위해 몇 파일에 걸쳐 나누어지고 싶습니다.

문제 없습니다. 그냥 사용하세요 부분적인 키워드를 사용하면 내부 클래스를 원하는 만큼 파일로 분할할 수 있습니다.같은 파일에 보관할 필요는 없습니다.

이전 답변:

가능하지만 반성해야만 가능

public abstract class AbstractClass
{
    public static AbstractClass MakeAbstractClass(string args)
    {
        if (args == "a")
            return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassA), true);
        if (args == "b")
            return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassB), true);
    }
}

public class ConcreteClassA : AbstractClass
{
    private ConcreteClassA()
    {
    }
}

public class ConcreteClassB : AbstractClass
{
    private ConcreteClassB()
    {
    }
}

그리고 여기에 추악하지 않은 또 다른 패턴이 있습니다. MakeAbstractClass(문자열 인수)

public abstract class AbstractClass<T> where T : AbstractClass<T>
{
    public static T MakeAbstractClass()
    {
        T value = (T)Activator.CreateInstance(typeof(T), true);
        // your processing logic
        return value;
    }
}

public class ConcreteClassA : AbstractClass<ConcreteClassA>
{
    private ConcreteClassA()
    {
    }
}

public class ConcreteClassB : AbstractClass<ConcreteClassB>
{
    private ConcreteClassB()
    {
    }
}

클래스가 동일한 어셈블리에 있으면 생성자를 내부로 만들 수 없습니까?

아니, 내 생각엔 우리가 그렇게 할 수 없을 것 같아.

다음에 이어 수락된 답변, 공용 인터페이스가 있고 전용 클래스가 인터페이스를 구현하도록 만든 경우 인터페이스에 대한 포인터를 반환할 수 있으며 부모 추상 클래스 외부의 모든 사람이 해당 포인터를 사용할 수 있습니다(자식 클래스는 여전히 숨겨져 있음).

당신은 실제로 필요 이것을하기 위해?실제 설계가 필요하지 않은 상태에서 일종의 의사 팩토리 패턴을 사용하는 경우 코드를 이해하고 유지 관리하고 확장하기가 더 어려워질 뿐입니다.

이 작업을 수행할 필요가 없으면 실제 팩토리 패턴을 구현하면 됩니다.또는 더 많은 ALTy를 사용하려면 DI/IoC 프레임워크를 사용하세요.

키워드를 사용할 수 없나요? partial 클래스의 코드를 여러 파일로 분할하는 방법은 무엇입니까?

별도의 서비스 어셈블리에서 이 클래스를 사용하는 경우 내부 키워드를 사용할 수 있습니다.

public class AbstractClass
{
    public AbstractClass ClassFactory(string args)
    {
        switch (args)
        {
            case "A":
                return new ConcreteClassA();               
            case "B":
                return new ConcreteClassB();               
            default:
                return null;
        }
    }
}

public class ConcreteClassA : AbstractClass
{
    internal ConcreteClassA(){ }
}

public class ConcreteClassB : AbstractClass
{
    internal ConcreteClassB() {}
}

당신이 해야 할 일은 기본 생성자가 생성되는 것을 방지하는 것입니다.클래스가 동일한 어셈블리에 없으면 내부를 공개로 변경할 수 있습니다.

public abstract class AbstractClass{

 public static AbstractClass MakeAbstractClass(string args)
 {
    if (args == "a")
        return ConcreteClassA().GetConcreteClassA();
    if (args == "b")
        return ConcreteClassB().GetConcreteClassB();
 }
}

public class ConcreteClassA : AbstractClass
{
  private ConcreteClassA(){}

  internal static ConcreteClassA GetConcreteClassA(){
       return ConcreteClassA();
  }
}

public class ConcreteClassB : AbstractClass
{
  private ConcreteClassB(){}
  internal static ConcreteClassB Get ConcreteClassB(){
       return ConcreteClassB();
  }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top