As a C# developer, you likely understand the importance of arrays for storing collections of data. However, when your data becomes more complex than simple types like strings or integers, you need a more advanced data structure – enter arrays of objects.
Object arrays allow you to store instances of classes in a single array variable for easy access and manipulation. They bring together the flexibility of object-oriented programming with the performance benefits of arrays.
In this comprehensive guide, we‘ll explore everything you need to know to effectively work with arrays of objects in your C# applications.
What is an Array of Objects?
An array of objects in C# allows you to store multiple reference type variable instances in a single array variable. The array itself is an object that contains other objects.
For example, consider a Book
class:
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
public int Pages { get; set; }
}
We can then create an array of Book
objects like:
Book[] books = new Book[3];
This array can hold three Book
instances. We can add book objects to it:
books[0] = new Book { Title = "Learn C#", Author = "Code Master", Pages = 500 };
books[1] = new Book { Title = "Algorithms", Author = "Cs Guru", Pages = 600 };
And so on. This keeps related objects together for easy access.
The key thing is that an array of objects groups reference type variables, unlike a simple value type array.
Why Use Arrays of Objects?
Object arrays serve two main purposes:
-
They allow you to store multiple instances of classes conveniently instead of having to declare individual variables constantly.
-
You can store objects of different classes/types in the same array if needed (via an object array).
For complex data structures and algorithms, arrays of objects make your code more readable and maintainable. You avoid cluttering the code with too many variables. Manipulating groups of related objects (like books, customers, products etc.) also becomes easier.
Additionally, features like sorting, searching and other algorithms are simpler on arrays.
So in OOP scenarios involving non-trivial data, arrays of objects just make sense!
Declaring and Initializing Arrays of Objects
The process looks similar to simple arrays:
// DataType[] arrayName;
Book[] books;
// Creating the actual array
books = new Book[5];
We declare the array variable books
to hold elements of type Book
. Then initialize a 5 element array of Book
using new Book[5]
.
We can even initialize the array on one line:
Book[] books = new Book[3];
Or use a collection initializer for brevity:
Book[] books = {
new Book { Title = "Learn C#", Author = "Code Master"},
new Book { Title = "Code Smart", Author = "Coder123" }
};
This creates the array and adds two Book
elements to it directly!
Note: Elements are automatically initialized to null/default values in reference type arrays – we still need to create the actual objects.
Accessing Elements in Object Arrays
We utilize indexers to access elements in C# arrays. The index starts from 0 till n-1 where n is the length of the array.
To get or set an object:
Book firstBook = books[0]; // Get first book
books[1] = someOtherBook; // Set 2nd book
We can also loop over elements:
foreach (Book b in books)
{
Console.WriteLine(b.Title);
}
This iterates over the books
array printing each book‘s title neatly!
Methods and Properties for Arrays of Objects
We have all familiar array features available like Length
property, Sort()
, Clear()
etc. These allow easy manipulation in C# code itself.
Some useful ones are:
- Length – gets total elements present
- Sort() – sorts elements by specified comparator
- Clear() – sets all elements to default value
- CopyTo() – copies elements to another array
And more! We also use methods from the System.Array
class frequently like BinarySearch(), Resize(), ConvertAll() etc.
Here is an example usage for sorting:
// Sort books by pages
Array.Sort(books, (x, y) => x.Pages.CompareTo(y.Pages));
// Sort by a separate comparer
Array.Sort(books, new BookComparer());
This enables productive work directly with object arrays!
Storing Mixed Types via Object Arrays
We can even store different unrelated types (like strings, ints etc.) in a single array through object
arrays:
object[] mixed = { "Hello", 10, true, new Person() };
The limitation is we lose the typing information and have to explicitly cast elements:
int number = (int)mixed[1];
Value and reference types work as expected even in mixed arrays.
While less common in practice than dedicated typed arrays, mixed object
arrays are useful for some interop scenarios.
Common Object Array Algorithms and Operations
Let‘s explore some representative examples of array of objects algorithms to see the concepts in action.
Searching the Array of Objects
Searching elements is a daily task. With object arrays, we can leverage C#‘s power:
// Book Search by property
static Book SearchByTitle(Book[] books, string title)
{
foreach(var book in books)
{
if(book.Title == title) return book;
}
return null; // Not found
}
// Call it like
Book result = SearchByTitle(bookArray, "Learn C#");
We can search books efficiently by any property without needing external search structures!
Sorting Array Elements
Sorting elements by some criteria is easy too:
// Sort books method
static void SortBooks(Book[] books)
{
// Sort using Title
Array.Sort(books, (b1, b2) => b1.Title.CompareTo(b2.Title));
// Sort by a specific comparer
Array.Sort(books, new BookComparer());
}
Using Array.Sort()
we leverage built-in quicksort for fast ordering. The same applies for other algorithms as well!
Storing in a Collection
We can store object arrays themselves inside collections like List:
// List of book arrays
List<Book[]> allBooks = new List<Book[]>();
Book[] firstBatch = GetBooksBatch();
allBooks.Add(firstBatch);
This keeps multiple arrays together in a highly dynamic list for scalable code!
Complex Custom Operations
We can also create custom complex logic around object arrays:
// Filter books released after 2000
Book[] recentBooks = FilterBooks(books, book => book.ReleaseDate > 2000);
// Calculate total pages in book inventory
int totalPages = CalculateTotalPages(books);
// Build alphabetically ordered author list
Author[] orderedAuthors = BuildAuthorIndex(books);
The OOP + array power combination is flexible enough for any domain!
When to Avoid Arrays of Objects
While object arrays are tremendously useful in many cases, there are a couple scenarios where alternatives like Lists may be preferable:
- When number of elements is unknown or likely to change frequently. Arrays are less dynamic than Lists.
- When storage requirements can radically change. Dynamic expansion is easier with Lists.
- When frequent insertion/deletion from middle is needed. Arrays require moving elements.
In these cases, leverage inbuilt List/Dictionary classes or custom collections for enhanced flexibility!
Advanced Scenarios and Alternatives
Let‘s go over some key advanced use cases around object arrays and alternatives available.
Lists for Flexible Object Collections
C#‘s List serves as a common alternative structure for variable collections:
List<Book> bookList = new List<Book>();
bookList.Add(book1);
bookList.Add(book2);
Lists allow dynamic growth and have O(1) insertion/deletion complexity making them great for fluid collections.
Do note that lists use arrays internally by default thus optimizing common operations!
Sets/HashSets for Unique Objects
For a collection of unique objects, HashSet shines:
HashSet<Author> authorSet = new HashSet<Author>();
authorSet.Add(new Author("RK Tanenbaum")); // Adds fine
authorSet.Add(new Author("RK Tanenbaum")); // No-op, already present!
HashSet provides uniqueness checking out of the box. And boast O(1) access via hashes internally.
Dictionaries for Keyed Access
If we wish to access objects via keys/ids rather than positions, C#‘s dictionaries rock:
// Key = book code, Value = Book object
Dictionary<string, Book> bookCodes = new Dictionary<string, Book>();
bookCodes.Add("0001", new Book { Title ="Learn ABC"});
bookCodes.Add("0002", new Book { Title ="Master XYZ"});
// Fetch book by key/code
Book myBook = bookCodes["0001"];
Dictionaries map keys to values for blazing fast lookup in large collections. Extremely versatile.
Custom Collection Classes
For advanced custom behavior around object collections, we can author our own collection classes by deriving from CollectionBase, implementing IList etc.
This allows crafting functionality like multi-value dictionaries, tree-based collections, composite arrays, priority queues etc.!
Tips and Best Practices
Let‘s round up the post with some handy tips:
- Initialize arrays to appropriate capacity to avoid wasteful resizing
- Sort object arrays for faster searching with algorithms like BinarySearch
- For uniform behavior, implement the IComparable interface on classes
- Use memory efficient value types like ints over classes as indexes
- Take advantage of built-in methods in Array/List/Dictionary classes first before writing custom iterative code
- Prefer lists over arrays when number of elements can vary significantly
- Use arrays of objects to organize logical groups of data elegantly
Master these and you will be leveraging one of most powerful constructs in C#!
Conclusion
Arrays of objects enable developers to elegantly work with object-oriented domains in C# code. We can organize business entities like products, employees, books naturally while enjoying array capabilities like indexing, sorting etc.
Key highlights:
- Arrays allow storing multiple instances of classes conveniently
- Can work with both strongly-typed and mixed object arrays
- Support many helpful algorithms like sorting, searching out of the box
- Integrate neatly with other collections like Lists, Dictionaries
- Enable modeling complex custom behavior and operations
So dive into arrays of objects to boost your C# application development today!