Come posso usare un tipo con argomenti generici come vincolo?
-
02-07-2019 - |
Domanda
Vorrei specificare un vincolo che è un altro tipo con un argomento generico.
class KeyFrame<T>
{
public float Time;
public T Value;
}
// I want any kind of Keyframe to be accepted
class Timeline<T> where T : Keyframe<*>
{
}
Ma questo non può ancora essere fatto in c # (e dubito davvero che lo sarà mai). Esiste una soluzione elegante a questo piuttosto che dover specificare il tipo dell'argomento keyframe ?:
class Timeline<TKeyframe, TKeyframeValue>
where TKeyframe : Keyframe<TKeyframeValue>,
{
}
Soluzione
Leggi questo a proposito di Eric Blog di Lippert Fondamentalmente, devi trovare un modo per fare riferimento al tipo desiderato senza specificare il parametro del tipo secondario.
Nel suo post, mostra questo esempio come possibile soluzione:
public abstract class FooBase
{
private FooBase() {} // Not inheritable by anyone else
public class Foo<U> : FooBase {...generic stuff ...}
... nongeneric stuff ...
}
public class Bar<T> where T: FooBase { ... }
...
new Bar<FooBase.Foo<string>>()
Spero che aiuti, Troy
Altri suggerimenti
Dato che TimeLine è molto probabilmente un'aggregazione di KeyFrames, non sarebbe simile a:
class TimeLine<T>
{
private IList<KeyFrame<T>> keyFrameList;
...
}
soddisfa bene le tue esigenze?
Se il tipo T che Timeline<T>
rappresenta è uguale al tipo KeyFrame<T>
rappresenta, puoi semplicemente scegliere:
class Timeline<T>
{
List<KeyFrame<T>> _frames = new List<KeyFrame<T>>(); //Or whatever...
...
}
Se il tipo T rappresenta qualcosa di diverso tra le classi, il che implica che KeyFrame
può contenere più tipi di <=>, nel qual caso è necessario creare un'implementazione più astratta di <=> e utilizzarla in <=>.
Forse l'annidamento Timeline
all'interno di KeyFrame
avrebbe senso nel tuo design:
class KeyFrame<T> {
public float Time;
public T Value;
class Timeline<U> where U : Keyframe<T> {
}
}