C# 如何枚举通用列表<;T>;不知其类型

C# 如何枚举通用列表<;T>;不知其类型,c#,C#,我正在向函数传递一个泛型列表,我想枚举列表中的对象。如果我能够列举列表中的项目,我将使用反射到其他项目 var Items= new List<String>(){"s1","s2"}; Enumerate(Items); void Enumerate(object items) { //i know the type so i can cast and enumerate foreach(var item in (List<St

我正在向函数传递一个泛型列表,我想枚举列表中的对象。如果我能够列举列表中的项目,我将使用反射到其他项目

 var Items= new List<String>(){"s1","s2"};
  Enumerate(Items);
  void Enumerate(object items)
  {
        //i know the type so i  can cast and enumerate
        foreach(var item in (List<String>) items)
        {

        }
        // i don't know the type of object in the list
        //Following won't work , can't cast to List<object> 
        foreach (var item in (List<object>) items)
        {

        }
    }
var Items=newlist(){“s1”,“s2”};
列举(项目);
无效枚举(对象项)
{
//我知道类型,所以我可以强制转换和枚举
foreach(列表项中的var项)
{
}
//我不知道列表中对象的类型
//以下内容无效,无法强制转换到列表
foreach(列表项中的var项)
{
}
}

您可以将函数设置为通用函数

public void Enum<T>(List<T> list)
        {
            foreach (T t in list)
            {

            }
        }
公共无效枚举(列表)
{
foreach(列表中的T)
{
}
}

我不确定你的最终目标是什么。如果您需要一个列表,特别是一个泛型列表,为什么不使用泛型方法,如:

void Enumerate<T>(List<T> items)
{
  for(var item in items) 
  {
    //...
  }
}
void枚举(列表项)
{
for(项目中的var项目)
{
//...
}
}
这将在中进行更详细的描述


我只想补充一点,上述方法本身就违背了简单for-in循环的目的。同样,我不知道Enumerate除了迭代项之外还要做什么。

您的函数的有效版本是:

var Items= new List<String>(){"s1","s2"};
Enumerate(Items);
void Enumerate<T>(List<T> items)
{
    if (typeof(T) == typeof(string))
    {
        //i know the type so i  can cast and enumerate
        foreach(string item in (List<String>) items)
        {

        }
    }
    else
    {
        // i don't know the type of object in the list
        //Following won't work , can't cast to List<object> 
        foreach (T item in items)
        {

        }
    }
}
var Items=newlist(){“s1”,“s2”};
列举(项目);
无效枚举(列表项)
{
if(typeof(T)=typeof(string))
{
//我知道类型,所以我可以强制转换和枚举
foreach(列表项中的字符串项)
{
}
}
其他的
{
//我不知道列表中对象的类型
//以下内容无效,无法强制转换到列表
foreach(项目中的T项目)
{
}
}
}
但这可以更好地写成:

void Enumerate<T>(List<T> items)
{
    foreach (T item in items)
    {
        if (typeof(T) == typeof(string))
        { /* Do something */ }
        else
        { /* Do something else */ }
    }
}
void枚举(列表项)
{
foreach(项目中的T项目)
{
if(typeof(T)=typeof(string))
{/*做点什么*/}
其他的
{/*做点别的*/}
}
}

我有一个静态类,其中有一些UTIL函数,比如列表中的字符串枚举器:

public static string EnumerateStrings<T>(this List<T> items, string separator = "; ")
{
    var result = "";

    if(typeof(T) == typeof(string) && items.SafeAny())
    {
        items.ForEach(str => {
            try
            {
                if (!String.IsNullOrEmpty(str as string))
                {
                    if (!String.IsNullOrEmpty(result))
                        result += separator;
                    result += str;
                }
            }
            catch { }
        });
    }

    return result;
}
您可以调整以使用更多对象类型

SafeAny()
的代码:

public static bool SafeAny(此IEnumerable列表,Func谓词)
{
返回列表!=null&&list.Any(谓词);
}

您不应该传递IEnumerable而不是Object吗?我如何将参数类型设置为IEnumerable,传递给函数的对象将始终是一个列表,但列表中对象的类型将有所不同。更大的问题是,为什么列表中有不同的对象?实现这一点的通常方法是使用复合设计模式……您不需要仅仅为了枚举而知道类型。如果你必须操纵,那么你肯定需要它。如果您必须验证具有相似特征的某些不同类型的对象,那么我建议您使用接口并枚举它。像` foreach(列表项中的var i)…@TheVillageIdiot:如果你一开始没有
列表,即使使用这样的接口在C 4.0之前也是很困难的。
string myCarsEnumeration = Cars.Select(ob => ob.Name).ToList().EnumerateStrings();
//output-> Porsche; Lexus; Peugeot

//or

string myCarsEnumeration2 = Cars.Select(ob => ob.Name).ToList().EnumerateStrings(", ");
//output-> Porsche, Lexus, Peugeot
public static bool SafeAny<T>(this IEnumerable<T> list, Func<T, bool> predicate)
{
    return list != null && list.Any(predicate);
}