1

I have a generic method and it's possible that the object passed is a single object or a list of objects. Example:

public void MyGenericMethod<T>(T something, int? index)
{
    // if it is a list how do I get to the object in the list?
}

There are cases when someone will pass a List. If they do pass a list of objects I will then use the index parameter to get the single object out of the list. I can assume that if index is not null then they passed in a list, but then how do I get to that value? I can't do this:

object temp = something[index.Value];

It's important to note that I cannot force the user to pass in a single object into my generic method. Also I cannot make it an array (T[]) and force the user to pass in an array (or a List).

5
  • 1
    var lst = something as IList; if (lst == null) { // something isn't a list } else { // something is a list } Commented Jul 10, 2013 at 15:27
  • @Corak It could be an array Commented Jul 10, 2013 at 15:28
  • @SimonBelanger Array implements IList too Commented Jul 10, 2013 at 15:30
  • @PeteBaughman Well darn. Never thought it did, but it makes sense. Does an array of T[] implements IList<T> ? Commented Jul 10, 2013 at 15:31
  • I believe so. You can cast a T[] to an IList<T> but you have to be a little careful. If you call the add method, for example, you'll get a NotSupportedException because the underlying array has a fixed size. Commented Jul 10, 2013 at 15:41

5 Answers 5

6

You can use a cast to get the IList.

IList list = something as IList;
if( list != null )
{
    object temp = list[index.Value];
}

However it might be simpler and more type safe to have a generic method overload dedicated to IList instead of one massive generic method.

public void MyGenericMethod<T>(IList<T> something, int index)
{
    var item = something[index];
    // etc...
}
Sign up to request clarification or add additional context in comments.

4 Comments

+1 for the 2nd part of this answer. The MyGenericMethod that takes a T instead of an IList<T> should just wrap the T up in a list and then call the IList<T> version
If I do the (IList)something cast I get this error: Using the generic type 'System.Collections.Generic.IList<T>' requires 1 type arguments.
The overload is the cleanest way. Check if index has a value. ^^;
@user78739 You might using the generic (IList<>)something which requires a parameter. IList is a separate non-generic interface.
1

Your requirements seem a bit wierd... why not do the following:

public void MyGenericMethod<T>(T something)
{
    // let the user pass in the correct item
}

And simply let the user handle it, after all how is:

MyGenericMethod(MyList, 1);

Significantly better than:

MyGenericMethod(MyList[1])

???

Though if you really want I'd write it like so:

public void MyGenericMethod<T>(T something) //Base Method
{
    // let the user pass in the correct item
}

public void MyGenericMethod<IList<T>>(IList<T> list, int index)  //Overload
{
    MyGenericMethod(list[index]);
}

Comments

0

Generics are meant to be used if your code does not care about the concrete type. If you still want to do this you need to cast:

IList list = (IList)something;

Or, if it is a generic list you need to do reflection access to invoke the list indexer at runtime if the element type is not statically known to you.

This (inefficient) snippet might also help you:

List<object> list = ((IEnumerable)something).Cast<object>().ToList();

Those are some ugly tricks. There is no clean way because, again, you are slightly misusing the feature.

Also, you don't need generics at all. Just type the parameter as object.

Comments

0

Like usr said, Generics aren't really supposed to be used in this way.

You could do a check to see if it's a list and if so iterate over it like this:

IList<T> enumerable = something as IList<T>;
if (enumerable != null)
{
    foreach (T item in enumerable)
    {
        // Do something
    }
}

Comments

0

If your T can be anything (which I don't recommend, since it breaks the SOLID principle) and what to handle it as a list you can do:

public void MyGenericMethod<T>(T something, int? index)
{
   IList list = something as IList;
   if (list != null)
   {
      //Do Something
   }
   else
   {
      //Do something else
   }
}

Or you can do one of the following:

public void MyGenericMethod<T>(T something, int? index) where T : IList
{
   IList list = (IList)something; //This will always work ok
   //Do Something
}

I recommend the following, if feasible

public void MyGenericMethod(IList something, int? index)
{
     //Do Something
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.