Imaginez une extension comme ça ..Quel est le "type" d'un IList générique <T>?
public static Blah<T>(this IList<T> ra)
{
..
}
Imaginez que vous voulez faire une note des plus récemment appelé un.
private static IList recent;
public static Blah<T>(this IList<T> ra)
{
recent = ra;
..
}
Vous pouvez réellement pas faire:
erreur CS0266: ne peut pas convertir implicitement le type
System.Collections.Generic.IList<T>
àSystem.Collections.IList
.
1- Vous pouvez simplement faire un recent
object
et qui semble fonctionner très bien, mais il semble comme une mauvaise solution.
2- Il semble si vous avez récemment en tant IList
, vous pouvez réellement lancer le « ra » que ...
recent = (System.Collections.IList)ra;
et il semble fonctionner. Cela semble étrange cependant? Ainsi,
3- En fait, quel type devrait être récent de sorte que vous ne devez pas jeter à elle ?? Comment pouvez-vous faire recent
le même type que ra
? Vous ne pouvez pas dire cela ...
private static System.Collections.Generic.IList recent;
ce n'est pas significatif. Alors, quel est le type de "ra"? Que devrait être recent
"être" de sorte que vous pouvez simplement dire recent=ra
?
(Je mentionne cela est pour l'unité, puisque vous utilisez constamment des extensions génériques dans l'unité.)
4- Tenir compte d'une difficulté supplémentaire le cas si vous voulez avoir un dictionnaire de tous.
private static Dictionary<object,int> recents = new Dictionary<object,int>();
Je peux vraiment seulement voir comment le faire comme un objet.
EXEMPLE DE CAS D'UTILISATION.
est ici une extension que vous utilisez en permanence, partout, dans l'ingénierie de jeu,
public static T AnyOne<T>(this IList<T> ra)
{
int k = ra.Count;
if (k<=0) {Debug.Log("Warn!"+k);}
int r = UnityEngine.Random.Range(0,k);
return ra[r];
}
aucun problème jusqu'à présent. Ainsi,
explosions.AnyOne();
yetAnotherEnemyToDefeat = dinosaurStyles.AnyOne();
et ainsi de suite. Toutefois. Bien sûr, les sélections aléatoires réelles se sentent mal; en pratique, ce que vous voulez est un ordre assez non-répétitif, plus comme un shuffle. Habituellement, la meilleure chose à faire avec une liste ou un tableau est de les mélanger et de les servir dans cet ordre; peut-être mélanger à nouveau à chaque fois. Exemple simple, vous avez 20 effets sonores aléatoires roars
, étant pour quand le dino rugit.Chaque fois que vous en avez besoin, si vous le faites
roars.AnyOne();
c'est OK, mais pas génial. Ça va sembler un peu nul. (La plupart des joueurs le signaleront comme "n'étant pas aléatoire" ou "répétant beaucoup".) Ceci
roars.NextOne();
est beaucoup mieux. Donc, NextOne()
devrait, en soi, (a) si nous sommes au début, mélangez la liste, (b) servez-la dans cet ordre, (c) peut-être remuez-la à nouveau chaque fois que vous utilisez la liste. {Il y a d'autres subtilités, par exemple, essayez de ne pas répéter la fin ou le début du remaniement, mais pas pertinent ici.}
Notez que sous-classer Liste (et/ou tableau) serait nul pour de nombreuses raisons évidentes, c'est un travail pour une extension autonome simple. Alors, voici une belle façon de mettre en œuvre NextOne()
en utilisant une simple extension avec état.
private static Dictionary<object,int> nextOne = new Dictionary<object,int>();
public static T NextOne<T>(this IList<T> ra)
{
if (! nextOne.ContainsKey(ra))
// i.e., we've never heard about this "ra" before
nextOne.Add(ra,0);
int index = nextOne[ra];
// time to shuffle?
if (index==0)
{
Debug.Log("shuffling!"); // be careful to mutate, don't change the ra!
IList<T> temp = ra.OrderBy(r => UnityEngine.Random.value).ToList();
ra.Clear(); foreach(T t in temp) ra.Add(t);
}
T result = ra[index];
++index;
index=index%ra.Count;
nextOne[ra] = index;
return result;
}
Ceci est sûrement l'exemple parfait d'une "extension avec état".
Remarque en effet, je viens d'utiliser "objet". En un sens, la question fondamentale dans ce QA est: est-il préférable d'utiliser le Dictionary of "object", ou est-ce que quelque chose de plus typé serait mieux? Vraiment c'est la question à portée de main. À votre santé!
Avoir une méthode statique qui maintient l'état statique semble vraiment mauvais pour moi. Je chercherais d'autres solutions qui n'impliquent pas cela. –
'IList' and'IList 'ne sont pas du même type, donc vous ne pouvez pas avoir une seule variable qui est les deux, puisqu'une variable n'a qu'un seul type. –
Salut Jeff - vous dites que vous n'aimez pas l'idée d'extensions qui sont stateful? – Fattie