Perché non posso creare un costruttore astratto su una class C # astratta?

Sto creando una class astratta. Voglio che ciascuna delle mie classi derivate sia forzata ad implementare una firma specifica del costruttore. Come tale, ho fatto quello che avrei fatto se volessi costringerli a implementare un metodo, ne ho fatto uno astratto.

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

Tuttavia ricevo un messaggio che dice che il modificatore astratto non è valido su questo elemento. Il mio objective era forzare un codice come questo.

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

Questo è tutto il codice C # .NET. Qualcuno mi può aiutare?

Aggiornamento 1

Volevo aggiungere alcune cose. Quello che ho finito è stato questo.

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

Questo fa quello che dicono alcuni, il default è privato e la class ha bisogno di implementare un costruttore. Tuttavia ciò non forza un costruttore con la firma A (int a, int b).

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

Aggiornamento 2

Dovrei essere chiaro, per ovviare a questo ho reso privato il mio costruttore di default e protetto il mio altro costruttore. Non sto davvero cercando un modo per far funzionare il mio codice. Mi sono preso cura di questo. Sto cercando di capire perché C # non ti permette di farlo.

Non è ansible avere un costruttore astratto perché astratto significa che è necessario sovrascriverlo in qualsiasi class figlio non astratta e non è ansible sovrascrivere un costruttore.

Se ci pensate, questo ha senso, dal momento che chiamate sempre il costruttore della class figlio (con il nuovo operatore) e mai la class base.

In generale, l’unico modo in C # per applicare una specifica firma del costruttore è usando il nuovo () vincolo generico, che impone l’esistenza di un costruttore senza parametri per il parametro type.

Cambia quel costruttore in class A in

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

Quindi le sottoclassi dovranno usarlo, in quanto non esiste un costruttore predefinito.

Tuttavia, possono comunque modificare la firma effettiva del costruttore. Non c’è modo di forzare una sottoclass a utilizzare una firma specifica per il suo costruttore, per quanto ne so. Sono abbastanza sicuro che i costruttori non possano essere astratti.

Per cosa esattamente hai bisogno di questo? Potremmo essere in grado di suggerire una soluzione per questo.

Sebbene non sia ansible sovrascrivere i costruttori e quindi non sia ansible definire un costruttore astratto, è ansible inserire un metodo factory astratto nella class base astratta. Tutte le classi derivate avrebbero bisogno di scavalcarlo.

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

Molte ragioni:

1) I costruttori non sono ereditati quindi non puoi sovrascriverli.

2) Il costruttore è una funzione membro statico poiché non ha bisogno di chiamare un’istanza specifica. L’astratto implica “virtuale”, il che significa che l’implementazione può variare a seconda di come un’istanza specifica viene sottoclassata, il che è l’opposto dell’intenzione del significato della parola chiave “statica”.

Non è ansible imporre la firma del costruttore, poiché ogni class derivata può (deve!) Definire i propri costruttori o i propri costruttori e possono prendere i parametri che preferiscono.

Se è necessario passare un determinato insieme di variabili a un object di una class derivata, definire un metodo astratto che deve essere implementato dalle classi derivate. Se le classi non implementano il metodo astratto, si otterrà un errore del compilatore.

Spero che questo possa aiutare qualcuno come me sto cercando di rendere una “normale” public class con un ctor che prende argomento e quindi ho bisogno di renderlo un child class quindi avevo bisogno di un ctor vuoto per questo.

non lo sapevo prima: se fai un ctor protetto allora la class bambino lo vede ma il resto del programma non lo vede (credo che la mia confusione sia da quando in asp.net vedo tutti i protetti nella pagina aspx che eredita da il cs …)

Tutte le sottoclassi possono sempre specificare il proprio costruttore purché chiamino un costruttore della superclass – quindi non c’è modo di forzare la class ad avere un costruttore specifico (Almeno, questo è il modo in cui funziona in Java). È ansible vedere l’utilizzo di un modello di fabbrica che ti porterà da qualche parte – potresti definire un metodo factory in un’interfaccia – ma avrai bisogno di una class factory separata in quanto la tua class base astratta non conosce la class effettiva dell’object che deve essere creato.

Tuttavia: forse aggiungere un esempio più concreto del problema che stai riscontrando potrebbe richiedere altre / migliori risposte. Stai cercando qualche codice di istanziazione generico o sei interessato a settaggi specifici sulla class base astratta?

Se si è solo preoccupati dell’inizializzazione che deve essere eseguita dalla class astratta, creare un metodo per farlo e documentare l’utilizzo di tale metodo.

non sono sicuro se questo aiuta – ma credo che questa sarebbe una soluzione al tuo problema:

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

con il risultato che è ansible chiamare un costruttore con gli argomenti richiesti in qualsiasi class derivata con il comportamento corretto.