If I would like to write a method that takes a variable number of "TDerived" where TDerived is any subclass of a class "Base", is there any way to do this?
The following code only works with a single specific specified subclass:
void doStuff<TDerived>(params TDerived[] args) where TDerived : Base
{
//stuff
}
ie if I have
class Super { }
class Sub0 : Super { }
class Sub1 : Super { }
then I cannot do
Sub0 s0 = new Sub0();
Sub1 s1 = new Sub1();
doStuff(s0, s1);
since I get "best overloaded match... has some invalid arguments".
Regardless of how the compiler handles the type constraints and variadic functions, this seems (as far as I can tell) completely type-safe. I know I could cast, but if this is type safe why not allow it?
EDIT:
Perhaps a more convincing example:
void doStuff<TDerived>(params SomeReadOnlyCollection<TDerived>[] args) where TDerived : Base
{
foreach(var list in args)
{
foreach(TDerived thing in list)
{
//stuff
}
}
}
TDerived
needs to be able to resolve to a single type. In your example, the only type it could resolve to would be Super
, but the compiler is not going to make that leap. You can make that leap for the compiler.
doStuff(new Super[] { s0, s1 });
doStuff<Super>(s0, s1);
Regarding your update, consider (instead of a generic method) defining a method accepting IEnumerable<ISuper>
, which will support derived types because IEnumerable<T>
is covariant (as of .NET 4). IEnumerable<T>
is also inherently readonly and forward-only, perfect if you have a foreach
loop. Full working example:
class Program
{
static void Main()
{
var sub0s = new Sub0[] { new Sub0() };
var sub1s = new List<Sub1> { new Sub1() };
doStuff(sub0s, sub1s);
}
static void doStuff(params IEnumerable<ISuper>[] args)
{
foreach (var sequence in args)
{
foreach (var obj in sequence)
{
Console.WriteLine(obj.GetType());
// you have the ability to invoke any method or access
// any property defined on ISuper
}
}
}
}
interface ISuper { }
class Super : ISuper { }
class Sub0 : Super { }
class Sub1 : Super { }
IEnumerable<T>
is implemented by BCL collections since .NET 2.0, including T[]
, List<T>
, ReadOnlyCollection<T>
, HashSet<T>
, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With