Questo non è consentito dal linguaggio C# come descritto nella sezione 4.4.3 della specifica Tipi associati e non associati.
Se il vincolo è il vincolo costruttore new()
, il tipo A
non deve essere abstract
e deve avere un costruttore senza parametri pubblica. Questo è soddisfatto se uno dei seguenti è vero.
A
è un tipo di valore, poiché tutti i tipi di valore hanno un costruttore predefinito pubblico
A
è un parametro tipo avente il vincolo cosntructor
A
è un parametro tipo avente il tipo di valore di vincolo
A
è una classe che non è abstract
e contiene un constatore esplicitamente dichiarato public
senza parametri
A
non è abstract
e ha un costruttore predefinito.
Un errore del compilatore se una di queste condizioni non viene soddisfatta. Se ti accorgi di avere tipi che sono pubblici ma solo con costruttori interni, allora molto probabilmente dovrebbero essere effettivamente tipi interni con costruttori pubblici.
Si consiglia di modificare il tipo di accesso a internal
e il suo costruttore su public
e renderlo senza parametri. Il costruttore senza parametri public
può quindi chiamare un costruttore non parametrico private
o internal
per eseguire ulteriori operazioni di inizializzazione.
internal class C<T> where : T new()
{
public C() : this(new T()) {
}
private C(T t) {
// Do additional initialization
}
}
Mente che modello è limitato, ma non c'è nulla ti impedisce di utilizzare un metodo di private
invece.
internal class C<T> where T : new() {
public C() {
T t = new T();
InitializeClass(t);
}
private void InitializeClass(T t) {
throw new NotImplementedException();
}
}
Come per il vostro aggiornamento, ecco un piccolo esempio di un picchetto pubblico singleton.
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() : this(new T()) {
}
private Singleton(T t) {
Current = this;
// Do whatever you need to with T
}
public String Name {
get;
set;
}
}
Uso
// Somewhere in your internal assembly
Singleton<String> singleton = new Singleton<String>();
// In an external assembly
Singleton.Current.Name = "SoMoS";
Non c'è nemmeno bisogno di utilizzare costruttori in quel modo sia, si può altrettanto facilmente fare qualcosa di semplice.
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() {
T t = new T();
// Do stuff with T
}
public String Name {
get;
set;
}
}
Generics non può essere la strada da percorrere se non è possibile progettare in base alle proprie esigenze. I generici possono fare così tanto e non risolvono ogni problema. Ci sono cose come Factory Pattern, Injection, ecc.
Rendi la classe interna e il costruttore pubblico. Se la classe deve essere pubblica, allora no non puoi. –