developer tip

추상 C # 클래스에서 추상 생성자를 만들 수없는 이유는 무엇입니까?

copycodes 2020. 12. 12. 11:29
반응형

추상 C # 클래스에서 추상 생성자를 만들 수없는 이유는 무엇입니까?


추상 클래스를 만들고 있습니다. 내 파생 클래스 각각이 생성자의 특정 서명을 구현하도록하고 싶습니다. 그래서 내가했던 일을해서 강제로 메소드를 구현하도록하고 추상적 인 것을 만들었습니다.

public abstract class A
{
    abstract A(int a, int b);
}

그러나 추상 수정자가이 항목에서 유효하지 않다는 메시지가 표시됩니다. 내 목표는 이와 같은 코드를 강제하는 것이 었습니다.

public class B : A
{
    public B(int a, int b) : base(a, b)
    {
        //Some other awesome code.
    }
}

이것은 모두 C # .NET 코드입니다. 누구든지 나를 도울 수 있습니까?

업데이트 1

몇 가지를 추가하고 싶었습니다. 내가 결국은 이것이었다.

private A() { }

protected A(int a, int b)
{
    //Code
}

그것은 일부 사람들이 말하는 것을 수행합니다. 기본값은 비공개이며 클래스는 생성자를 구현해야합니다. 그러나 그것은 서명 A (int a, int b)를 가진 생성자를 강제하지 않습니다.

public abstract class A
{
    protected abstract A(int a, int b)
    {


    }
}

업데이트 2

이 문제를 해결하기 위해 기본 생성자를 비공개로 설정하고 다른 생성자를 보호했습니다. 나는 정말로 내 코드를 작동시키는 방법을 찾고 있지 않습니다. 내가 처리 했어. 나는 왜 C #이 이것을 허용하지 않는지 이해하고 싶습니다.


abstract는 추상이 아닌 자식 클래스에서이를 재정의해야하고 생성자를 재정의 할 수 없음을 의미하기 때문에 추상 생성자를 가질 수 없습니다.

생각해 보면 이것은 항상 자식 클래스의 생성자 (new 연산자 사용)를 호출하고 기본 클래스는 호출하지 않기 때문에 의미가 있습니다.

일반적으로 C #에서 특정 생성자 서명을 적용하는 유일한 방법은 new () 제네릭 제약 조건 을 사용하는 것입니다.이 제약 조건은 형식 매개 변수에 대해 매개 변수가없는 생성자의 존재를 적용합니다.


클래스 A의 생성자를 다음으로 변경하십시오.

protected A(int a, int b)
{
    // Some initialisation code here
}

그러면 기본 생성자가 없으므로 하위 클래스에서이를 사용해야합니다.

그러나 여전히 생성자의 실제 서명을 변경할 수 있습니다. 내가 아는 한 하위 클래스가 생성자에 특정 서명을 사용하도록 강제하는 방법은 없습니다. 나는 생성자가 추상적 일 수 없다고 확신합니다.

정확히 무엇을 위해 필요합니까? 이에 대한 해결 방법을 제안 할 수 있습니다.


생성자를 재정의 할 수 없으므로 추상 생성자를 정의 할 수 없지만 추상 기본 클래스에 추상 팩토리 메서드를 배치 할 수 있습니다. 모든 파생 클래스는이를 재정의해야합니다.

public abstract class A 
{ 
    abstract A MakeAInstance(int a, int b); 
} 

public class B : A 
{ 
    // Must implement:
    override A MakeAInstance(int a, int b) {
        // Awesome way to create a B instance goes here
    }
} 

여러 가지 이유 :

1) 생성자는 상속되지 않으므로 재정의 할 수 없습니다.

2) The constructor is a static member function since it dont need a specific instance to be called. Abstract implies "virtual" which means that the implementation can vary depending on how a specific instance is subclassed, which is the opposite of the intention of the meaning of the "static" keyword.


You cannot enforce constructor signature, as each derived class may (must!) define its own constructor(s), and they may take any parameters they like.

If you need to pass a given set of variables to an object of a derived class, define an abstract method which needs to be implemented by derived classes. If the classes do not implement the abstract method, you will get a compiler error.


hope this will help someone newb as i am i was looking to make a "normal" public class with a ctor that takes argument and then i needed to make it a child class so i needed an empty ctor for it.

i didnt know this before: if you make a protected ctor then the child class sees it but the rest of the program dont see it (i guess my confusion is since in asp.net i see all the protected in the aspx page which inherits from the cs...)


All subclasses always can specify their own constructor as long as they call a constructor of the superclass - so there is no way of forcing the a class to have a specific constructor (At least, that is the way it works in Java). You could see of using a factory pattern will get you somewhere - you could define a factory method in an interface - but you'll need a separate factory class as your abstract base class does not know the actual class of the object that needs to be created.

However: maybe adding a more concrete example of the issue you are having might prompt other/better responses. Are you looking for some generic instantiation code, or are you concerned specific settings on the abstract base class have to be done?

If you are just concerned about initialization that has to be done by the abstract class, create a method to do so, and document the usage of that method.


not sure if this helps - but i feel this would be a solution to your problem:

public class A
{
  public A(int a, int b)
  {
    DoSomething(int a, int b);
  }

  virtual public void DoSomething(int a, int b)
  {

  }
}

public class B : A
{
  override public void DoSomething(int a, int b)
  {
    //class specific stuff
  }
}

with the result that you can call a constructor with the required arguments in any derived class with the correct behaviour.

참고URL : https://stackoverflow.com/questions/504977/why-cant-i-create-an-abstract-constructor-on-an-abstract-c-sharp-class

반응형