泛型方法,如果它是List,如何获取值

本文关键字:获取 何获取 如果 List 泛型方法 | 更新日期: 2023-09-27 18:21:54

我有一个通用方法,传递的对象可能是单个对象或对象列表。示例:

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

在某些情况下,有人会通过列表。如果他们确实传递了一个对象列表,我将使用index参数从列表中获取单个对象。我可以假设,如果index不为null,那么他们会传入一个列表,但我如何获得该值?我不能这样做:

object temp = something[index.Value];

需要注意的是,我不能强迫用户将单个对象传递到我的泛型方法中。此外,我不能使它成为数组(T[])并强制用户传入数组(或List)。

泛型方法,如果它是List,如何获取值

您可以使用强制转换来获取IList

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

然而,使用一个专用于IList的泛型方法重载而不是一个大型泛型方法可能更简单,也更安全。

public void MyGenericMethod<T>(IList<T> something, int index)
{
    var item = something[index];
    // etc...
}

您的需求似乎有点模糊。。。为什么不做以下操作:

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

并且简单地让用户处理它,毕竟是怎么回事:

MyGenericMethod(MyList, 1);

明显优于:

MyGenericMethod(MyList[1])

不过如果你真的想的话,我会这样写:

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]);
}

如果您的代码不关心具体的类型,就应该使用泛型。如果你仍然想这样做,你需要铸造:

IList list = (IList)something;

或者,如果它是一个泛型列表,如果元素类型不是静态已知的,则需要在运行时进行反射访问以调用列表索引器。

这个(低效的)片段也可能对您有所帮助:

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

这些是一些丑陋的把戏。没有干净的方法,因为再一次,您有点滥用了该功能。

此外,您根本不需要泛型。只需将参数键入为object即可。

正如usr所说,泛型实际上不应该以这种方式使用。

你可以做一个检查,看看它是否是一个列表,如果是,像这样迭代:

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

如果你的T可以是任何东西(我不建议这样做,因为它打破了SOLID原则),以及如何将其作为列表处理,你可以做:

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

或者您可以执行以下操作之一:

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

如果可行,我推荐以下

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