Keywords: C# | multi-dimensional list | generic collections
Abstract: This article explores various methods for implementing multi-dimensional lists in C#, focusing on generic List<List<T>> structures and dictionary-based multi-dimensional list implementations. Through detailed code examples, it demonstrates how to create dynamic multi-dimensional data structures with add/delete capabilities, comparing the advantages and disadvantages of different approaches. The discussion extends to custom class extensions for enhanced functionality, providing practical solutions for C# developers working with complex data structures.
Background of Multi-dimensional List Requirements
In C# programming, multi-dimensional arrays (e.g., string[,] results = new string[20, 2];) provide fixed-size multi-dimensional data structures but lack dynamic resizing capabilities. In practical development, there is often a need for multi-dimensional collections that can dynamically add and remove elements, which is precisely where multi-dimensional lists (or lists of lists) find their application.
Basic Implementation: List of Lists
The simplest implementation of a multi-dimensional list uses the List<List<T>> structure. This approach directly leverages C# generic collections to create a nested structure where an outer list contains multiple inner lists. For example:
List<List<string>> results = new List<List<string>>();
results.Add(new List<string>());
results[0].Add("example string");
string value = results[0][0];The advantage of this method is its simplicity, using standard collection classes without additional encapsulation. However, it requires multiple levels of indexing for access and lacks unified dimension management.
Advanced Encapsulation: Generic Multi-dimensional List Class
To improve code readability and maintainability, specialized multi-dimensional list classes can be created. By inheriting from List<List<T>>, a multi-dimensional collection with clear semantics can be established:
public class MultiDimList<T> : List<List<T>> { }Usage example:
var multiList = new MultiDimList<string>();
multiList.Add(new List<string> { "first row", "data" });
multiList[0].Add("new element");This encapsulation makes multi-dimensional list usage more intuitive while preserving all functionalities of List<T>.
Dictionary-based Multi-dimensional Lists
For multi-dimensional data requiring key-based access, dictionary structures can be employed. By creating classes that inherit from Dictionary<K, List<T>>, key-value pair style multi-dimensional collections can be implemented:
public class MultiDimDictList<K, T> : Dictionary<K, List<T>>
{
public void Add(K key, T item)
{
if (!ContainsKey(key))
base.Add(key, new List<T>());
if (!base[key].Contains(item))
base[key].Add(item);
}
}Usage example:
var dictList = new MultiDimDictList<string, int>();
dictList.Add("ages", 25);
dictList.Add("ages", 30);
dictList.Add("salaries", 50000);This approach is particularly suitable for scenarios requiring data organization by categories, such as statistical collections under different classifications.
Nested Multi-dimensional Dictionary Lists
For more complex data structures, multi-level nested dictionary lists can be implemented. By extending the MultiDimDictList class, data structures supporting multi-level key access can be created:
public class NestedMultiDimDictList<K, K2, T> : MultiDimDictList<K, MultiDimDictList<K2, T>>
{
public void Add(K key, K2 subKey, T item)
{
if (!ContainsKey(key))
base.Add(key, new MultiDimDictList<K2, T>());
if (!base[key].ContainsKey(subKey))
base[key].Add(subKey, item);
}
}This structure is suitable for data requiring multi-level classification, such as employee information statistics by department and position.
Performance and Application Scenario Analysis
Different multi-dimensional list implementations have distinct advantages and disadvantages:
List<List<T>>: Suitable for scenarios with fixed dimensions requiring sequential access, with higher memory efficiencyMultiDimList<T>: Provides better encapsulation, suitable as part of public APIsMultiDimDictList<K, T>: Suitable for scenarios requiring fast key-based lookup, but with greater memory overhead- Nested structures: Suitable for complex data relationships, but with increased access complexity
In practical applications, appropriate data structures should be selected based on data access patterns and performance requirements.
Best Practice Recommendations
1. For simple two-dimensional data, prefer List<List<T>> or MultiDimList<T>
2. Use dictionary-based implementations when key-based categorical access is needed
3. Consider implementing indexers or extension methods to simplify access syntax
4. Pay attention to thread safety, using appropriate synchronization mechanisms in multi-threaded environments
5. For large datasets, consider specialized data structure libraries or databases
By appropriately selecting and implementing multi-dimensional list approaches, various complex data structure requirements can be efficiently handled in C#.