Esiste un modo per specificare che un tipo generico sia di un tipo o un altro tipo?Specificare un vincolo generico C# per essere di Classe A O Classe B?
public class SoftDrink<T>
where T : TypeOne or TypeTwo
{ }
Esiste un modo per specificare che un tipo generico sia di un tipo o un altro tipo?Specificare un vincolo generico C# per essere di Classe A O Classe B?
public class SoftDrink<T>
where T : TypeOne or TypeTwo
{ }
No perché non avrebbe alcun senso. Se si tenta di accedere a una funzione membro di "T", come può il compilatore indicare quale classe di base provare e risolvere i membri di?
Si potrebbe provare a creare un'interfaccia comune per TypeOne e TypeTwo e avendo il vincolo specificare tale interfaccia? Cosa stai cercando di realizzare, esattamente?
No, tuttavia, è possibile limitare la classe su una base o un'interfaccia comune.
Nello stesso CLR, i vincoli (ad eccezione di quelli speciali, come il nuovo vincolo) sono memorizzati piuttosto semplicemente: solo un elenco di identificatori di tipo, in pratica. Quindi non c'è davvero "spazio" per le operazioni logiche come hai specificato ... non senza una revisione delle specifiche CLR, o forse alcuni trucchi a livello di linguaggio davvero intelligenti e brutti.
È possibile estrarre la funzionalità comune di TypeOne e TypeTwo in una classe base o un'interfaccia e utilizzare tale classe di base o interfaccia come vincolo. Altrimenti, come potrebbe il compilatore sapere cosa potrebbe fare con T
?
public interface IBelch
{
void Belch();
}
public class Coke : IBelch
{
public void Belch()
{
}
}
public class GatorAde : IBelch
{
public void Belch()
{
}
}
public class SoftDrink<T>
where T : IBelch
{
public void DrinkFast(T drink)
{
drink.Belch();
}
}
Non è possibile. Il meglio che puoi fare è usare una classe base comune per i due, o un'interfaccia comune implementata da entrambi come un vincolo di tipo singolo.
Si potrebbe avere TypeOne e TypeTwo ereditare un'interfaccia e quindi effettuare le seguenti operazioni.
public class SoftDrink<T>
where T: IMyType
{}
Si può sempre fare un controllo di esecuzione contro il tipo:
class TypeOne
{
int _integer = 0;
}
class TypeTwo
{
int _integer = 3;
}
class TypeThree
{
}
class SoftDrink<T>
{
public SoftDrink()
{
if (typeof(T) != typeof(TypeOne) && typeof(T) != typeof(TypeTwo))
{
throw (new Exception("Sorry, but T must be TypeOne or TypeTwo"));
}
}
}
//this works:
SoftDrink<TypeOne> t1 = new SoftDrink<TypeThree>();
//throws an exception:
SoftDrink<TypeThree> t3 = new SoftDrink<TypeThree>();
Aggh, bastonatemi di un minuto; Stavo per suggerire la stessa cosa. Certo, non è vero O-O, ma funzionerebbe. –
Stavo solo cercando di risolvere un particolare problema senza mettere le due classi sotto un interfacce o base simile classe. – Scott
Se approfondisci il problema che stai riscontrando, forse possiamo aiutarti a trovare una soluzione alternativa! :) – Sapph
Beh, era più una curiosità che altro. Fondamentalmente, ci sono due metodi in FormatXML, uno che ha preso TypeA, l'altro TypeB. Una soluzione facile sarebbe quella di avere TypeA e TypeB implementare IXMLFormattable o qualcosa di simile. – Scott