ПРИМІТКА: Ця публікація виявилася набагато детальнішою і тому поза темою, прошу вибачення.
Як сказано, мої однолітки читали це і вважають, що це «десь». Цій нитці не місце. Буду вдячний за ваші відгуки про те, куди це має йти (я новачок на сайті).
У будь-якому випадку це версія C # в .NET 3.5, яка дивовижна тим, що вона працює на будь-якому типі колекції з використанням визначеної семантики. Це міра за замовчуванням (повторне використання!), Неефективність або мінімізація циклу процесора в найбільш поширених сценаріях розробників, хоча це ніколи не відбувається у реальному світі (передчасна оптимізація).
*** Метод розширення, що працює над будь-яким типом колекції та приймає делегата дії, очікуючи єдиного значення типу, всі виконані над кожним елементом у зворотному порядку **
Потрібно 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Старіші версії .NET чи ви хочете краще зрозуміти внутрішність Linq? Читай далі .. Або ні ..
ПЕРЕДАЧА: У системі типу .NET тип масиву успадковується від інтерфейсу IEnumerable (не загального IEnumerable тільки IEnumerable).
Це все, що вам потрібно повторити від початку до кінця, проте ви хочете рухатись у зворотному напрямку. Оскільки IEnumerable працює над масивом типу 'object', будь-який тип є дійсним,
КРИТИЧНИЙ ВИМІР: Ми припускаємо, що якщо ви можете обробити будь-яку послідовність у зворотному порядку, який є "кращим", то зможете це зробити лише на цілі числа.
Рішення для .NET CLR 2.0-3.0:
Опис: Ми приймемо будь-який екземпляр IEnumerable, який має мандат, який містить кожен екземпляр одного типу. Отже, якщо ми отримуємо масив, весь масив містить екземпляри типу X. Якщо будь-які інші екземпляри типу! = X, викидається виняток:
Одномісна послуга:
публічний клас 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] тестування публічного класу123 {
/// <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;
}
}