I've created the following generic method
protected int GetSpecifiedIndexByName<T>(T collection, string itemName)
{
int count = 0;
foreach (MyElement claim in collection)
{
if (itemName.Equals(claim.Name))
{
return count;
}
count++;
}
}
You have two problems with this method. One is that there is no proof that T : IEnumerable. You need to use a where clause to specify that. The other problem is that not all control paths lead to a return statement.
You shouldn't be using generics for this kind of behavior. Instead, you should just have the function take an object that implements the IEnumerable interface:
protected int GetSpecifiedIndexByName(IEnumerable collection, string itemName)
{
int count = 0;
foreach (MyElement claim in collection)
{
if (itemName.Equals(claim.Name))
{
return count;
}
count++;
}
return -1;
}
You could also use IEnumerable<MyElement> in the signature. This is a good idea because it more tightly defines the interface of the function.
protected int GetSpecifiedIndexByName(IEnumerable<MyElement> collection, string itemName)
{
...
}
So, you should not be trying to implement a generic function at all. You just want a function that takes a parameter of type IEnumerable<MyElement>.
I cannot cast the generic collection to the known collection directly i.e.
In general, you can't cast from one type to an unrelated type. For example, you can't cast something from Int32 to ArrayList. This is because there's no way that can be correct! Similarly, you can't cast a generic type, which could be anything, to the type MyCollection. You can only cast things to superclasses and subclasses of the type you're casting.
But have to take the intermediary step
Object foo = collection;
MyCollection foobar = (MyCollection)foo;
In this example, you've cast up to Object (which is allowed because Object is a superclass of everything) and then you've cast down to MyCollection (which is allowed because MyCollection is a subclass of Object). The fact that you wish to do such a thing means you're trying to use the type system the wrong way, and I've already described how.
By the way, here's another possible way to write the function you want. It uses the where clause that I mentioned at the beginning of my reply. This would be a spurious use of generics, though, since generics are only useful when you want to prove that two types are equal.
protected int GetSpecifiedIndexByName<T>(T collection, string itemName)
where T : IEnumerable<MyElement>
{
int count = 0;
foreach (MyElement claim in collection)
{
if (itemName.Equals(claim.Name))
{
return count;
}
count++;
}
return -1;
}