2008-08-21 2 views
5

나는 내가 만든 추상 클래스에서 상속 한 클래스의 컬렉션을 가지고있다. 추상 클래스의 구체적인 구현 인스턴스를 생성하는 팩토리로 추상 클래스를 사용하고 싶습니다.생성자를 C#의 상위 클래스에서만 볼 수있게 만드는 방법이 있습니까?

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

나는이 기본적으로

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 
{ 
} 

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

UPDATE
나는 추상 클래스의 외부에서 특정 ConcreteClassA의 방법 또는 B에 액세스 할 필요가 없습니다. 필자는 Abstract 클래스에서 제공하는 public 메소드 만 필요로한다. 필자는 Concrete 클래스가 인스턴스화되는 것을 막을 필요가 없다. 새로운 public 인터페이스를 제공하지 않기 때문에 그냥 피하려고 노력하고있다. 추상 클래스의 내부에서 매우 특정한 것들을 다르게 구현한다.

나에게 가장 간단한 해결책은 make child classes as samjudson mentioned입니다. 그러나 나는 이것을 피하고 싶다. 왜냐하면 내 추상 클래스의 파일을 내가 원하는 것보다 훨씬 더 크게 만들 것이기 ​​때문이다. 차라리 조직을위한 몇 가지 파일을 통해 클래스를 분리하여 보관하고 싶습니다.

나는이에 대한 쉬운 해결책이 없다 생각 ...

답변

2

이 같은 서브 클래스의 자식 클래스, 뭔가를 할 수 있습니다 : 이것은 실제로 클래스도 숨겨져 있음을 의미 하는가

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을 사용하면 다른 사람이 언급 한 것처럼 실제로 위와 같은 경우에 해당하는 Reflection을 사용하여 수행 할 수 있습니다. 예를 들어 위의 메소드는 동일한 파일 내부의 구체적인 클래스에 대한 응답입니다. 아마 매우 편리하지 않은 Abstract 클래스. 이 방법은 좋은 'Hack'이라고 말했고, 구체적인 클래스의 수와 복잡성이 낮 으면 좋을 것입니다.

+0

좋은 예입니다.하지만 .NETy를 조금 더 이름을 짓고 코딩 표준 인 "CreateAbstractClass (string args)"라고 부릅니다. :) –

1

아니, 나는 우리가 그렇게 할 수 있다고 생각하지 않습니다.

3

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

0

실제로 이 필요합니까?이 작업을 수행 하시겠습니까? 진정한 디자인이 필요없는 의사 (pseudo) 팩토리 패턴을 사용하고 있다면 코드를 이해, 유지 및 확장하기가 더 어려워 질 것입니다.

이 작업을 수행 할 필요가없는 경우 실제 팩터 리 패턴을 구현하기 만하면됩니다. 또는 더 많은 것은 DI/IoC 프레임 워크를 사용하십시오.

6

나를 위해, 가장 간단한 해결책은 언급 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() 
    { 
    } 
} 
-2

당신 기본 생성자가 생성되지 않도록하려면이 작업을 수행해야합니다. 클래스가 동일한 어셈블리에 없으면 내부 변수가 public으로 변경 될 수 있습니다.

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(); 
    } 

} 
0

클래스의 코드를 여러 파일로 분할하는 데 키워드 partial을 사용할 수 없습니까?

0

이 클래스를 별도의 서비스 어셈블리에서 사용하는 경우 internal 키워드를 사용할 수 있습니다. 공용 인터페이스를 가지고와 민간 클래스는 인터페이스를 구현 한 경우

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() {} 
} 
1

당신이 (당신의 부모 추상 클래스는 다음을 사용할 수있는 외부 인터페이스와 사람에 대한 포인터를 반환 그런 다음 accepted answer에서 수에 따라 아이 클래스를 숨기는 동안).

관련 문제