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