views:

41

answers:

2

Suppose I have two functions:

Foo(params INotifyPropertyChanged[] items)
{
   //do stuff
}

Foo<T>(IEnumerable<T> items) where T : INotifyPropertyChanged
{
   Foo(items.ToArray();
}

The second one allows me to call Foo from a generic class with the constraint where T : INotifyPropertyChanged, but the second resolves to itself so I get a stack overflow exception.

  1. Is it possible to specify which overload I want to call when there's some ambiguity?
  2. Is there another way to call a params function from a generic class, assuming the generic type's constraints make it a viable option for the params type?

Thanks in advance!

+3  A: 

You could try casting the input.

Foo<T>(IEnumerable<T> items) where T : INotifyPropertyChanged
{
   Foo(items.Cast<INotifyPropertyChanged>().ToArray());
}

If this doesn't work, I don't have an idea, you are probably out of luck.

Femaref
The code you provide selects Foo<T> overload, it is guarantee of stack overflowing.
STO
@STO: I don't think so. **EDIT** I tried it; it won't.
SLaks
@STO: Are you sure? Have you tried running it?
Mark Byers
This worked for me.
Jake
Sorry, my wrong. I seem first function have Foo(params object[] items) signature.
STO
+3  A: 

You need to pass a INotifyPropertyChanged[], not a T[].
For example:

Foo<T>(IEnumerable<T> items) where T : INotifyPropertyChanged
{
   Foo(items.Cast<INotifyPropertyChanged>().ToArray());
}

In general, however, it's better to call the IEnumerable version from the params version, like this:

Foo(params INotifyPropertyChanged[] items)
{
   Foo((IEnumerable<INotifyPropertyChanged>) items);
}

Foo<T>(IEnumerable<T> items) where T : INotifyPropertyChanged
{
   //do stuff
}
SLaks
Cannot convert type 'T[]' to 'System.ComponentModel.INotifyPropertyChanged[]'
Mark Byers
@Mark: Yes; I just tried that. Fixed.
SLaks
Going with this answer because the latter option removes any possible ambiguity - the first one is more compiler trickery.
Jake