REMARQUE: Ce message a fini par être beaucoup plus détaillé et donc hors sujet, je m'excuse.
Cela étant dit, mes pairs le lisent et pensent qu'il est utile «quelque part». Ce fil n'est pas l'endroit. J'apprécierais vos commentaires sur où cela devrait aller (je suis nouveau sur le site).
Quoi qu'il en soit, c'est la version C # dans .NET 3.5 qui est incroyable en ce qu'elle fonctionne sur n'importe quel type de collection en utilisant la sémantique définie. Il s'agit d'une mesure par défaut (réutilisation!) Et non de la minimisation des performances ou du cycle du processeur dans la plupart des scénarios de développement courants, bien que cela ne semble jamais être ce qui se passe dans le monde réel (optimisation prématurée).
*** Méthode d'extension travaillant sur n'importe quel type de collection et prenant un délégué d'action attend une valeur unique du type, le tout exécuté sur chaque élément à l'envers **
Requres 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Anciennes versions de .NET ou souhaitez-vous mieux comprendre les composants internes de Linq? Continuez à lire… Ou pas…
HYPOTHÈSE: Dans le système de type .NET, le type Array hérite de l'interface IEnumerable (et non du IEnumerable générique uniquement IEnumerable).
C'est tout ce dont vous avez besoin pour parcourir du début à la fin, mais vous souhaitez vous déplacer dans la direction opposée. Comme IEnumerable fonctionne sur un tableau de type 'objet', tout type est valide,
MESURE CRITIQUE: Nous supposons que si vous pouvez traiter n'importe quelle séquence dans l'ordre inverse qui est «meilleure», alors ne pouvoir le faire que sur des entiers.
Solution a pour .NET CLR 2.0-3.0:
Description: Nous accepterons toute instance d'implémentation IEnumerable avec le mandat que chaque instance qu'elle contient est du même type. Donc, si nous recevons un tableau, le tableau entier contient des instances de type X. Si d'autres instances sont d'un type! = X, une exception est levée:
Un service singleton:
classe publique ReverserService {private ReverserService () {}
/// <summary>
/// Most importantly uses yield command for efficiency
/// </summary>
/// <param name="enumerableInstance"></param>
/// <returns></returns>
public static IEnumerable ToReveresed(IEnumerable enumerableInstance)
{
if (enumerableInstance == null)
{
throw new ArgumentNullException("enumerableInstance");
}
// First we need to move forwarad and create a temp
// copy of a type that allows us to move backwards
// We can use ArrayList for this as the concrete
// type
IList reversedEnumerable = new ArrayList();
IEnumerator tempEnumerator = enumerableInstance.GetEnumerator();
while (tempEnumerator.MoveNext())
{
reversedEnumerable.Add(tempEnumerator.Current);
}
// Now we do the standard reverse over this using yield to return
// the result
// NOTE: This is an immutable result by design. That is
// a design goal for this simple question as well as most other set related
// requirements, which is why Linq results are immutable for example
// In fact this is foundational code to understand Linq
for (var i = reversedEnumerable.Count - 1; i >= 0; i--)
{
yield return reversedEnumerable[i];
}
}
}
public static class ExtensionMethods
{
public static IEnumerable ToReveresed(this IEnumerable enumerableInstance)
{
return ReverserService.ToReveresed(enumerableInstance);
}
}
[TestFixture] classe publique Testing123 {
/// <summary>
/// .NET 1.1 CLR
/// </summary>
[Test]
public void Tester_fornet_1_dot_1()
{
const int initialSize = 1000;
// Create the baseline data
int[] myArray = new int[initialSize];
for (var i = 0; i < initialSize; i++)
{
myArray[i] = i + 1;
}
IEnumerable _revered = ReverserService.ToReveresed(myArray);
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_why_this_is_good()
{
ArrayList names = new ArrayList();
names.Add("Jim");
names.Add("Bob");
names.Add("Eric");
names.Add("Sam");
IEnumerable _revered = ReverserService.ToReveresed(names);
Assert.IsTrue(TestAndGetResult(_revered).Equals("Sam"));
}
[Test]
public void tester_extension_method()
{
// Extension Methods No Linq (Linq does this for you as I will show)
var enumerableOfInt = Enumerable.Range(1, 1000);
// Use Extension Method - which simply wraps older clr code
IEnumerable _revered = enumerableOfInt.ToReveresed();
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_linq_3_dot_5_clr()
{
// Extension Methods No Linq (Linq does this for you as I will show)
IEnumerable enumerableOfInt = Enumerable.Range(1, 1000);
// Reverse is Linq (which is are extension methods off IEnumerable<T>
// Note you must case IEnumerable (non generic) using OfType or Cast
IEnumerable _revered = enumerableOfInt.Cast<int>().Reverse();
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_final_and_recommended_colution()
{
var enumerableOfInt = Enumerable.Range(1, 1000);
enumerableOfInt.PerformOverReversed(i => Debug.WriteLine(i));
}
private static object TestAndGetResult(IEnumerable enumerableIn)
{
// IEnumerable x = ReverserService.ToReveresed(names);
Assert.IsTrue(enumerableIn != null);
IEnumerator _test = enumerableIn.GetEnumerator();
// Move to first
Assert.IsTrue(_test.MoveNext());
return _test.Current;
}
}