🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11: Microsoft entfernt WMIC-Tool gegen Ransomware - ad-hoc-news.de(14.09.2026 um 07:58 Uhr)
🕵️ SicherheitslückenMicrosoft schließt Rekordzahl an Sicherheitslücken - techbook(14.09.2026 um 09:00 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11: Microsoft entfernt WMIC-Tool gegen Ransomware - ad-hoc-news.de(14.09.2026 um 07:58 Uhr)
🕵️ SicherheitslückenMicrosoft schließt Rekordzahl an Sicherheitslücken - techbook(14.09.2026 um 09:00 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 5 Min Lesezeit
0

Completing the Paginator Class in C#

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Learn how to design and implement an efficient Paginator class in C# for sorting and paginating large datasets. Discover lazy evaluation, read-only collections, and custom page handling to optimize performance and scalability. Perfect for developers handling complex data operations!



The Paginator class represents a powerful collection for paginated data. It allows users to sort, segment, and work with data efficiently through pages. In this article, we'll discuss how to finalize the design and implementation of this class, including how to address key issues related to performance and usability.









Final Features of the Paginator





  1. Page Size and Page Count:




    • The paginator calculates the total number of pages based on the list size and page size.




  2. Bounds Checking:




    • The paginator ensures that page offsets are within valid bounds, preventing out-of-range access.




  3. Lazy Pagination:




    • Pages are constructed on demand, ensuring efficient memory usage and minimal overhead for unused pages.




  4. Enumeration:




    • The paginator implements IEnumerable<IPage<T>> to allow iteration over pages.











Class Implementation



Let’s walk through the complete implementation of the Paginator class, including its key components.






Paginator Class






CODE
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class Paginator<T> : IPaginatedCollection<T>
{
private readonly Lazy<IReadOnlyList<T>> _sortedData;
private readonly int _pageSize;

public Paginator(IEnumerable<T> source, int pageSize, Func<T, object> sortKeySelector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize), "Page size must be greater than zero.");
if (sortKeySelector == null) throw new ArgumentNullException(nameof(sortKeySelector));

_pageSize = pageSize;

// Lazy initialization of sorted read-only list
_sortedData = new Lazy<IReadOnlyList<T>>(() => source.OrderBy(sortKeySelector).ToList().AsReadOnly());
}

public int PageCount => (int)Math.Ceiling((double)_sortedData.Value.Count / _pageSize);

public IPage<T> this[int index]
{
get
{
if (index < 0 || index >= PageCount)
throw new ArgumentOutOfRangeException(nameof(index), "Page index is out of range.");

// Create a new page on demand
return new ProjectingPage<T>(_sortedData.Value, index + 1, _pageSize);
}
}

public IEnumerator<IPage<T>> GetEnumerator()
{
for (int i = 0; i < PageCount; i++)
{
yield return this[i];
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}












ProjectingPage Class



The ProjectingPage class represents a view into the shared, sorted list, exposing a segment defined by its offset and size.




CODE
public class ProjectingPage<T> : IPage<T>
{
private readonly IReadOnlyList<T> _source;
private readonly int _offset;
private readonly int _upperOffset;

public ProjectingPage(IReadOnlyList<T> source, int ordinal, int pageSize)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (ordinal < 1) throw new ArgumentOutOfRangeException(nameof(ordinal), "Ordinal must be 1 or greater.");
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize), "Page size must be greater than zero.");

_source = source;

// Calculate offsets
_offset = (ordinal - 1) * pageSize;
_upperOffset = Math.Min(_offset + pageSize, _source.Count);

if (_offset >= _source.Count)
{
_offset = _source.Count;
_upperOffset = _source.Count;
}

Ordinal = ordinal;
PageSize = pageSize;
}

public int Ordinal { get; }
public int Count => _upperOffset - _offset;
public int PageSize { get; }

public IEnumerator<T> GetEnumerator()
{
for (int i = _offset; i < _upperOffset; i++)
{
yield return _source[i];
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}












Performance Analysis



The current design is efficient for iterating through all pages, but issues arise when only a subset of the data is accessed.






Problem: Cost of Full Evaluation





  • Scenario: Accessing the first page results in sorting the entire dataset, even if no additional pages are accessed.


  • Impact: The first page bears the full cost of sorting and initializing the entire collection.






Solution: Deferred Execution




  • Consider deferring sorting and page construction to occur only when needed.

  • Use smarter caching mechanisms to reduce redundant computations.









Example Usage



Here’s how you can use the paginator with a custom dataset:




CODE
class Program
{
static void Main()
{
var workers = new List<Worker>
{
new Worker { Name = "Alice", PayRate = 50 },
new Worker { Name = "Bob", PayRate = 40 },
new Worker { Name = "Charlie", PayRate = 60 },
new Worker { Name = "Diana", PayRate = 55 },
new Worker { Name = "Edward", PayRate = 45 }
};

var paginator = new Paginator<Worker>(
workers,
pageSize: 2,
sortKeySelector: w => w.PayRate // Sort by pay rate
);

Console.WriteLine($"Total Pages: {paginator.PageCount}");

foreach (var page in paginator)
{
Console.WriteLine($"Page {page.Ordinal}:");
foreach (var worker in page)
{
Console.WriteLine($"{worker.Name}: ${worker.PayRate}");
}
}
}
}

public class Worker
{
public string Name { get; set; }
public decimal PayRate { get; set; }
}












Output






CODE
Total Pages: 3
Page 1:
Bob: $40
Edward: $45
Page 2:
Alice: $50
Diana: $55
Page 3:
Charlie: $60












Performance Testing



To stress-test the paginator:




  1. Replicate the dataset to create a large number of workers.

  2. Measure time taken to fetch the first page and iterate through subsequent pages.

  3. Adjust page size and observe the impact on performance.






Example Stress Test






CODE
var replicatedWorkers = workers.Replicate(100000, w => 
new Worker
{
Name = w.Name,
PayRate = w.PayRate * (decimal)(1 + (new Random().NextDouble() - 0.5) * 0.1)
});

var paginator = new Paginator<Worker>(
replicatedWorkers,
pageSize: 100,
sortKeySelector: w => w.PayRate
);

var timer = Stopwatch.StartNew();

foreach (var page in paginator)
{
Console.WriteLine($"Page {page.Ordinal} - Average PayRate: {page.AveragePayRate()}");
timer.Restart();
}












Key Takeaways





  1. Flexibility:




    • The paginator supports any data type and sorting criteria, making it highly reusable.




  2. Efficiency:




    • Lazy evaluation ensures sorting happens only when required, and short-lived objects minimize garbage collection overhead.




  3. Challenges:




    • The cost of sorting can be significant for large datasets when only a subset is required.




  4. Future Enhancements:




    • Explore caching strategies for frequently accessed pages.

    • Optimize sorting for scenarios where only the top results are needed.





The Paginator class demonstrates the power of encapsulating complex operations like sorting and pagination into a simple, reusable abstraction.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
The Gemini desktop app is now available for Windows
1 Quelle
Burn Out, Or Fade Away
1 Quelle
Windows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Completing the Paginator Class in C#

Thematisch verwandte Begriffe: Completing, Paginator, Class · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...