Eredita da una classe base generica, applica un vincolo e implementa un'interfaccia in C #


117

Questa è una domanda di sintassi. Ho una classe generica che eredita da una classe base generica e applica un vincolo a uno dei parametri di tipo. Voglio anche che la classe derivata implementi un'interfaccia. Per la vita di me, non riesco a capire la sintassi corretta.

Questo è quello che ho:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

La prima cosa che mi è venuta in mente è stata questa:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Ma questo non è corretto in quanto ciò fa sì che T2 debba implementare sia IBar che IFoo, non DerivedFoo per implementare IFoo.

Ho provato un po 'di ricerca su Google, uso di due punti, punto e virgola, ecc., Ma sono risultato breve. Sono sicuro che la risposta sia semplicissima.


Non sono riuscito a capire la risposta di @ Adam quando ho guardato una volta, ma dopo 2 minuti ho potuto ottenere quello che è, grazie per la risposta. La classe derivata ha più di un'implementazione potrebbe essere questo il punto. Comunque voglio mostrare la sua notazione per gli altri. "class DerivedClass <Type>: ParentClass dove Type: IType". Niente dovrebbe essere tra l'ultima classe implementata e la clausola where.
nurisezgin

Risposte:


173

Includete l'intera firma della vostra classe prima di definire i vincoli generici.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}

5
Per altri, l'ho interiorizzato come, una classe ottiene solo una clausola where e va alla fine per tutti i vincoli di tipo generico.
Andy V

@Visser È consentito avere più clausole where, classe Test <T1, T2> dove T1: Interface1 dove T2: Interface2
bwing

@Visser sì, cosa ha detto bwing, anche ogni clausola where può avere più vincoli ... quindi la sintassi del post originale è corretta, significa solo qualcosa di diverso che l'opera voleva. where T2 : IBar, IFoo significa solo che T2deve implementare entrambe le interfacce invece di DerivedFoo<T1,T2> implementareIFoo
v01pe

18

Il mio consiglio: quando hai una domanda sulla sintassi del linguaggio C #, leggi le specifiche; ecco perché lo pubblichiamo. Ti consigliamo di leggere la sezione 10.1.

Per rispondere alla tua domanda specifica, l'ordine delle cose in una dichiarazione di classe è:

  • attributi, tra parentesi quadre
  • modificatori ("public", "static" e così via)
  • "parziale"
  • "classe"
  • il nome della classe
  • un elenco separato da virgole di dichiarazioni di parametri di tipo all'interno di parentesi angolari
  • i due punti seguono un elenco separato da virgole di tipi di base (classe base e interfacce implementate, la classe base deve essere inserita per prima se ce n'è una)
  • tipo vincoli di parametro
  • il corpo della classe, circondato da parentesi graffe
  • un punto e virgola

Tutto su quell'elenco è facoltativo tranne "classe", il nome e il corpo, ma tutto deve apparire in questo ordine se appare.


95
Eric, anche se ti rispetto molto come professionista e apprezzo il tuo feedback, non posso fare a meno di essere frustrato da quella che appare come una risposta abrasiva. Mi stai criticando per aver scelto di porre una domanda su un sito di domande e risposte sulla programmazione invece di individuare, scaricare e cercare in un documento Word altamente tecnico di 503 pagine sepolto da un collegamento in MSDN. Questo è piuttosto duro. Questo è stato l'uso più efficiente del mio tempo e ha l'ulteriore vantaggio di poter aiutare qualcun altro in seguito. Il collegamento alla specifica C # Lang per gli interessati è: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby

17
Nessuna critica era intesa. C'è un pregiudizio pervasivo nella comunicazione di testo puro che fa sembrare semplici dichiarazioni di fatti brusche e abrasive; Cerco di leggere in modo caritatevole quando mi viene presentato un elenco di fatti utili e vi consiglio di farlo anche voi. Sono fedele alla mia raccomandazione; se hai domande sulla sintassi, la specifica risponde in modo definitivo e inizia con un utile sommario per individuare le definizioni di sintassi specifiche.
Eric Lippert

3
Dan, trovare le specifiche C # è semplice come inserire "C # Spec" in Google e premere il pulsante "Sono fortunato". E se sei uno sviluppatore C # professionista, dovresti già avere le specifiche C # in formato PDF sul tuo computer. Inoltre, non intendo nemmeno criticare te. Non ero abituato a leggere le specifiche prima, ma ho iniziato a leggerlo grazie a Jon, Eric e Pavel che citano sempre le specifiche C # per qualsiasi domanda. Ho scoperto che le specifiche C #, anche se a volte potrebbero essere difficili da leggere, sono un ottimo modo per imparare la lingua.
Soluzione

@ Eric Lippert: abbastanza giusto. Grazie per la risposta. Come suggerimento costruttivo, sarebbe utile se Microsoft integrasse il contenuto della specifica direttamente in MSDN oltre a farlo esistere come download separato. La versione MSDN di Visual Studio .Net ha una versione integrata della specifica, ma non versioni successive. Ho pensato all'acquisto del libro di Anders Hejlberg, ma con .Net 4.0 dietro l'angolo sono ancora riluttante. amazon.com/C-Programming-Language-3rd/dp/0321562992 Grazie.
Dan Rigby

2
C ++ richiede che una dichiarazione di classe termini con un punto e virgola. Molti sviluppatori C # provengono da un background C ++; a volte le loro dita inseriscono il punto e virgola senza che il loro cervello sia coinvolto. :-) Ci sono un certo numero di costrutti in C # che accettano un semi facoltativo dove C ++ ne richiede uno. È praticamente solo una sottile comodità. Suppongo che ti permetta anche di richiamare sottilmente quando una dichiarazione di tipo sta finendo vs diciamo una dichiarazione del corpo del metodo.
Eric Lippert

8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }

2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Questa è un'estensione delle risposte esistenti. Il valore predefinito è stringse non si fornisce un tipo. Non ho implementato un'interfaccia ma ciò non dovrebbe richiedere nulla di diverso dal solito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.