Como posso usar um tipo de argumentos genéricos como uma restrição?
-
02-07-2019 - |
Pergunta
Eu gostaria de especificar uma restrição que é outro tipo com um argumento genérico.
class KeyFrame<T>
{
public float Time;
public T Value;
}
// I want any kind of Keyframe to be accepted
class Timeline<T> where T : Keyframe<*>
{
}
Mas isso não pode ser feito em c # como ainda, (e eu realmente duvido que ele nunca vai ser). Existe alguma solução elegante para isso ao invés de ter que especificar o tipo do argumento quadro-chave:?
class Timeline<TKeyframe, TKeyframeValue>
where TKeyframe : Keyframe<TKeyframeValue>,
{
}
Solução
Leia sobre isso a partir Eric de Lippert do blog Basicamente, você tem que encontrar uma maneira de se referir ao tipo que você quiser, sem especificar o parâmetro de tipo secundário.
Em seu post, ele mostra este exemplo como uma solução possível:
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>>()
Espero que ajude, Troy
Outras dicas
Como TimeLine é mais provável uma agregação de KeyFrames, não seria algo como:
class TimeLine<T>
{
private IList<KeyFrame<T>> keyFrameList;
...
}
cumprir suas exigências bem?
Se o tipo T que Timeline<T>
representa é o mesmo que o tipo KeyFrame<T>
representa você pode simplesmente ir com:
class Timeline<T>
{
List<KeyFrame<T>> _frames = new List<KeyFrame<T>>(); //Or whatever...
...
}
Se o tipo T representa diferentes algo entre as classes que implica que Timeline<T>
pode conter vários tipos de KeyFrame
do caso em que você deve criar uma implementação mais abstrata de KeyFrame
e usar isso em Timeline<T>
.
Timeline
Talvez nidificação dentro KeyFrame
faria sentido em seu design:
class KeyFrame<T> {
public float Time;
public T Value;
class Timeline<U> where U : Keyframe<T> {
}
}