I have types that looks like the following:
public class Test1
{
[SubTests]
List<SubTest1> SubTests { get; set; } = [];
public void Run()
{
foreach(var subtest in SubTests)
{
// ...
}
}
public class SubTest1 : ISubTest { }
}
public class Test2
{
[SubTests]
List<SubTest2> SubTests { get; set; } = [];
public void Run()
{
foreach(var subtest in SubTests)
{
// ...
}
}
public class SubTest2 : ISubTest { }
}
public interface ISubTest { }
I want to use reflection to add the elements of Test.SubTests
to a BindingList<ISubTest>
, but I don't know the type of the ISubTest
at compile time.
I tried getting the list like this:
foreach (var property in type.GetProperties())
{
if (property.GetCustomAttribute<SubTestsAttribute>() != null)
{
var subTests = (IList<ISubStep>)property.GetValue(valueSource);
return new BindingList<ISubstep>(subTests)
}
}
But that throws an InvalidCastException
because the type of the generic parameter to IList<>
is different.
Is there any way to do what I'm trying to do?
I think you need to manually add elements with foreach. IList<T>
is not covariant (no out
).
foreach (var property in type.GetProperties()) {
if (property.GetCustomAttribute<SubTestsAttribute>() != null) {
var subTests = (IEnumerable<ISubStep>)property.GetValue(valueSource);
var bindingList= new BindingList<ISubstep>();
foreach (var element in subTests) {
bindingList.Add(element);
}
return bindingList;
}
}
EDIT: FWIW, I didn't know this was a duplicate when answering - but thanks for the two downvotes. That definitely should teach me a lesson in what the "consensus" is.