CATATAN: Posting ini akhirnya menjadi jauh lebih rinci dan karena itu keluar dari topik, saya minta maaf.
Itu dikatakan rekan-rekan saya membacanya dan percaya itu berharga 'di suatu tempat'. Utas ini bukan tempatnya. Saya sangat menghargai umpan balik Anda tentang ke mana ini harus pergi (saya baru di situs ini).
Bagaimanapun ini adalah versi C # di .NET 3.5 yang luar biasa karena ia bekerja pada semua jenis koleksi menggunakan semantik yang ditentukan. Ini adalah ukuran default (gunakan kembali!), Bukan kinerja atau minimalisasi siklus CPU dalam skenario dev yang paling umum meskipun tampaknya tidak pernah terjadi di dunia nyata (pengoptimalan prematur).
*** Metode ekstensi bekerja pada semua jenis koleksi dan mengambil delegasi tindakan yang mengharapkan satu nilai dari jenis tersebut, semuanya dijalankan secara terbalik pada setiap item **
Requres 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Versi .NET yang lebih lama atau Anda ingin memahami internal Linq dengan lebih baik? Baca terus .. Atau tidak ..
ASUMSI: Dalam sistem tipe .NET, tipe Array mewarisi dari antarmuka IEnumerable (bukan IEnumerable generik hanya IEnumerable).
Ini semua yang Anda butuhkan untuk mengulang dari awal hingga akhir, namun Anda ingin bergerak ke arah yang berlawanan. Karena IEnumerable bekerja pada Array tipe 'objek', tipe apa pun valid,
TINDAKAN KRITIS: Kami berasumsi jika Anda dapat memproses urutan apa pun dalam urutan terbalik yang 'lebih baik' maka hanya dapat melakukannya pada bilangan bulat.
Solusi a untuk .NET CLR 2.0-3.0:
Deskripsi: Kami akan menerima semua contoh implementasi IEnumerable dengan mandat bahwa setiap contoh yang dikandungnya adalah dari jenis yang sama. Jadi jika kita menerima sebuah array, seluruh array berisi instance tipe X. Jika ada instance lain yang bertipe! = X pengecualian dilemparkan:
Layanan tunggal:
public class 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] kelas publik 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;
}
}