Invoke child generic classes' methods using reflection C#
Hello Guys,
Today I’m going to share you some practical usage of reflection that I faced it before.
Think that;
You have a class and inside class there are some generic classes based the same class.
And you want to call the same method of these generic classes.
At this point Reflection makes our job easy. With reflection you can reach all these generic classes and invoke their same method.
Sample tells better;
We will have a child class named Collector. It will be a generic class.
public class Collector<T>
{
private readonly List<T> bag;
public Collector() => bag = new();
public void AddBag(T item) => bag.Add(item);
public void RemoveBag(T item) => bag.Remove(item);
public void Clear() => bag.Clear();
public string GetAllItems()
{
if (!bag.Any())
return $"No items in collection with type {typeof(T).Name}";
return String.Join(", ", bag);
}
}
And we have the parent class named CollectorManager which has many Collector<> child classes.
public class CollectorManager
{
private List<int> a = new();
public Collector<int> IntCollector { get; set; }
public Collector<String> StringCollector { get; set; }
public Collector<double> DoubleCollector { get; set; }
public CollectorManager()
{
IntCollector = new();
StringCollector = new();
DoubleCollector = new();
}
// Instead of doing this
// public void ClearAllCollectors(){
// IntCollector.Clear();
// StringCollector.Clear();
// DoubleCollector.Clear();
// }
public void ClearAllCollectors()
{
//get all public properties
var allProperties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
//filter only Collector<T> types
var allCollectorTypes = allProperties.Where(p => p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == typeof(Collector<>));
foreach (var collector in allCollectorTypes)
{
Type collectorType = typeof(Collector<>);
//find generic of collector
Type genericCollectorType = collectorType.MakeGenericType(collector.PropertyType.GetGenericArguments()[0]);
//invoke Clear method of collector
genericCollectorType?.GetMethod("Clear")?.Invoke(collector.GetValue(this), null);
}
}
}
And we want to call “Clear” method of all child classes . Of course we can do it easily with;
public void clearallcollectors(){
Intcollector.clear();
Stringcollector.clear();
Doublecollector.clear();
}
But maybe later a new child class will be added into the parent class so this new class “Clear” method should be added inside “clearAllCollectors” method.
Instead, we can use the power of Reflection.
By using reflection we will find the child classes and call “Clear” methods of each one;
public void ClearAllCollectors()
{
//get all public properties
var allProperties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
//filter only Collector<T> types
var allCollectorTypes = allProperties.Where(p => p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == typeof(Collector<>));
foreach (var collector in allCollectorTypes)
{
Type collectorType = typeof(Collector<>);
//find generic of collector
Type genericCollectorType = collectorType.MakeGenericType(collector.PropertyType.GetGenericArguments()[0]);
//invoke Clear method of collector
genericCollectorType?.GetMethod("Clear")?.Invoke(collector.GetValue(this), null);
}
}
Thanks for reading. See you soon 😄