2017-12-11 4 views
2

기본 생성자에서 하위 클래스 생성자를 호출하고 기본 클래스 개체로 만든 하위 클래스 개체를 갖고 싶습니다. 코드는 다음과 같습니다.C에서 기본 생성자의 하위 클래스 생성자 호출

class Text 
{ 
    public string OriginalText; 

    public Text() { } 

    public Text(string text) 
    { 
     OriginalText = text; 
     text = FormatText(text); // like text.ToUpper().Trim() 

     if (Category1.Check(text)) 
      new Category1(text); 
     else if (Category2.Check(text)) 
      new Category2(text); 
     else if (Category3.Check(text)) 
      new Category3(text); 
    } 

} 

class Category1 : Text 
{ 
    public string Property1; 
    public Category1(string text) 
    { 
     Property1 = text + "#1"; 
    } 

    static public bool Check(string text) 
    { 
     return text == "category1"; 
    } 
} 

class Category2 : Text 
{ 
    public string Property2; 
    public Category2(string text) 
    { 
     Property2 = text + "(2)"; 
    } 

    static public bool Check(string text) 
    { 
     return text == "category2"; 
    } 
} 

class Category3 : Text 
{ 
    public string Property3; 
    public Category3(string text) 
    { 
     Property3 = text + "%3"; 
    } 

    static public bool Check(string text) 
    { 
     return text == "category3"; 
    } 
} 

그러나 var t = new Text("category1")는 서브 클래스의 목적이 아니었다. 나는 t is Category1false 인 것을 확인하여 검사했다. 나는 returnnew Category1(text) 앞에 추가하려고 시도했지만 생성자가 void 유형을 반환하기 때문에이 접근법은 실패했습니다. 다음은 일본어로 번역 된 오류 메시지입니다. 이 문제를 해결하기 위해

An object statement can't be used after the keyword return since MainWindow.Text.Text(string)' returns void type 

방법 중 하나는 서브 클래스 객체를 반환하는 정적 메서드를 정의한다. 이 정적 메소드이기 때문에

static public Text GetCategory(string text) 
{ 
    text = FormatText(text); 
    if (Category1.Check(text)) 
     return new Category1(text); 
    else if (Category2.Check(text)) 
     return new Category2(text); 
    else if (Category3.Check(text)) 
     return new Category3(text); 
    return null; 
} 

그러나 이번에 OriginalText = text;는 사용될 수 없다. 나는 if 문 모든 하위 클래스 생성자에서

string tmp1 = text; 
text = FormatText(text); 
var c1 = new Category1(text); 
c1.OriginalText = tmp1; 
return c1; 

또는 설정 OriginalText의 내용의 모든

하나 하나에 다음 코드를 추가하여 하나이 처리 할 수 ​​인정한다.

하지만 이렇게하면 코드가 길어지고 중복되고 읽기 및 유지가 어려워집니다. 공통된 프로세스를 같은 장소에 모으고 싶습니다. 기본 생성자입니다.

Google의 "call subclass constructor C#"은 저에게 답이 아닌 2 개의 기사를주었습니다.

  1. Calling subclass constructor from static base class method
    이는 무관하다. 그것은 기본 클래스에서 상속 된 정적 하위 클래스 메서드를 호출하는 것입니다.

  2. How to call subclass constructor only in inheritence
    이것은 다릅니다. 이것은 기본 클래스 생성자를 호출하지 않고 하위 클래스 생성자를 호출하는 것입니다.

어떻게이 문제를 해결할 수 있습니까?

+1

"기본 생성자에서 하위 클래스 생성자를 호출하고 생성 된 하위 클래스 객체를 기본 클래스 객체로 갖고 싶습니다." "기본 클래스 객체"와 같은 것은 없습니다. 하나의 개체 만 만들어지고 형식은 처음부터 정확합니다. 그것은 당신이 정말로 원하는 것이 정적 팩토리 메쏘드 인 것처럼 보입니다. –

+0

* "OriginalText = text, 정적 메서드이기 때문에 사용할 수 없습니다."* - 가능합니다. 그것은'public'입니다. 같은 줄에'return'과'new'를 사용하는 대신에 별도의 코드 행을 사용하십시오. 'new' 객체를 만들고 그 객체에 값을 설정 한 다음 그 객체를 반환하십시오. 'this'에 그 값을 설정할 수는 없지만 어쨌든 그것을 설정하고 싶지는 않습니다. 반환되는 객체 인스턴스에 설정하려고합니다. – David

답변

2
당신이, 당신이 새로운 인스턴스를 생성하는 얘기 코드 블록에서

있지만 변수에 할당되지 않습니다 그것은 하나 생성자에서 반환 할 수 없습니다

if (Category1.Check(text)) 
    new Category1(text); // <-- wrong! 

생성자는 주어진 타입의 메모리에서 새로 생성 된 공간을 초기화하는 메소드. 생성자에서 유형을 변경할 수 없습니다!

두 번째 예제에서 제공 한 것과 같은 공장 패턴이 필요합니다. 그게 최선의 유일한 옵션입니다 :

static public Text GetCategory(string text) 
{ 
    text = FormatText(text); 
    if (Category1.Check(text)) 
     return new Category1(text); 
0

패트릭은 올바르게 말하면서 공장 패턴을 사용하려고합니다. OriginalText에 대해서는이 코드를 반복하지 않아도됩니다.단순히 다음과 같은 팩토리 메서드를 작성하십시오.

static public Text GetCategory(string text) 
{ 
    var formattedText = FormatText(text); 
    Text result = null; 
    if (Category1.Check(formattedText)) 
     result = new Category1(formattedText); 
    else if (Category2.Check(formattedText)) 
     result = new Category2(formattedText); 
    else if (Category3.Check(formattedText)) 
     result = new Category3(formattedText); 
    if(result != null) 
     result.OriginalText = text; 
    return result; 
}