LƯU Ý: Bài đăng này đã trở nên chi tiết hơn nhiều và do đó lạc đề, tôi xin lỗi.
Điều đó được nói rằng các đồng nghiệp của tôi đã đọc nó và tin rằng nó có giá trị 'ở đâu đó'. Chủ đề này không phải là nơi. Tôi sẽ đánh giá cao phản hồi của bạn về việc điều này sẽ đi đến đâu (tôi mới sử dụng trang web).
Dù sao đây cũng là phiên bản C # trong .NET 3.5, điều tuyệt vời là nó hoạt động trên bất kỳ loại bộ sưu tập nào bằng cách sử dụng ngữ nghĩa đã xác định. Đây là thước đo mặc định (sử dụng lại!) Không phải là hiệu suất hoặc giảm thiểu chu kỳ CPU trong hầu hết các kịch bản phát triển phổ biến mặc dù điều đó dường như không bao giờ xảy ra trong thế giới thực (tối ưu hóa sớm).
*** Phương thức mở rộng hoạt động trên bất kỳ loại tập hợp nào và thực hiện một đại biểu hành động mong đợi một giá trị duy nhất của loại, tất cả được thực thi ngược lại trên từng mục **
Yêu cầu 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Phiên bản .NET cũ hơn hoặc bạn muốn hiểu rõ hơn về nội bộ Linq? Đọc tiếp .. Hoặc không ..
ASSUMPTION: Trong hệ thống kiểu .NET, kiểu Mảng kế thừa từ giao diện IEnumerable (không phải IEnumerable chung chỉ IEnumerable).
Đây là tất cả những gì bạn cần lặp lại từ đầu đến cuối, tuy nhiên bạn muốn di chuyển theo hướng ngược lại. Vì IEnumerable hoạt động trên Mảng kiểu 'đối tượng' nên bất kỳ kiểu nào cũng hợp lệ,
ĐO LƯỜNG TIÊU CHUẨN: Chúng tôi giả định nếu bạn có thể xử lý bất kỳ chuỗi nào theo thứ tự ngược lại 'tốt hơn' thì chỉ có thể thực hiện trên số nguyên.
Giải pháp a cho .NET CLR 2.0-3.0:
Mô tả: Chúng tôi sẽ chấp nhận bất kỳ cá thể triển khai IEnumerable nào với nhiệm vụ rằng mỗi thể hiện nó chứa là cùng một loại. Vì vậy, nếu chúng ta nhận được một mảng, toàn bộ mảng chứa các thể hiện kiểu X. Nếu bất kỳ trường hợp nào khác thuộc kiểu! = X, một ngoại lệ được ném ra:
Một dịch vụ singleton:
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] lớp công khai 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;
}
}