通用列表< T>作为IEnumerable< object> [英] Generic List<T> as IEnumerable<object>
问题描述
我正在尝试将列表强制转换为IEnumerable,因此我可以验证不同的列表不为null或为空:
I'm trying to do cast a List to an IEnumerable, so I can verify that different lists are not null or empty:
假设myList是一个列表< ; T>。然后在调用方代码中,我想要:
Suppose myList is a List < T > . Then in the caller code I wanted:
Validator.VerifyNotNullOrEmpty(myList as IEnumerable<object>,
@"myList",
@"ClassName.MethodName");
验证代码为:
public static void VerifyNotNullOrEmpty(IEnumerable<object> theIEnumerable,
string theIEnumerableName,
string theVerifyingPosition)
{
string errMsg = theVerifyingPosition + " " + theIEnumerableName;
if (theIEnumerable == null)
{
errMsg += @" is null";
Debug.Assert(false);
throw new ApplicationException(errMsg);
}
else if (theIEnumerable.Count() == 0)
{
errMsg += @" is empty";
Debug.Assert(false);
throw new ApplicationException(errMsg);
}
}
但是,这不起作用。它可以编译,但是IEnumerable为空!为什么?
However, this doens't work. It compiles, but theIEnumerable is null! Why?
推荐答案
IEnumerable< object>
不是 IEnumerable< T>
,因此它也不是 List< T>
的超类型。请参阅问题2575363 ,以简要了解这是为什么情况(关于Java,但概念相同)。顺便说一下,此问题已在C#4.0中解决,该问题支持协变泛型。
IEnumerable<object>
is not a supertype of IEnumerable<T>
, so it is not a supertype of List<T>
either. See question 2575363 for a brief overview of why this is the case (it's about Java, but the concepts are the same). This problem has been solved in C# 4.0, by the way, which supports covariant generics.
未找到此错误的原因是因为您将 x用作T
,应该使用常规强制转换((T)x
),请参见问题2139798 。结果 InvalidCastException
会指出您的错误。 (实际上,如果类型关系正确(即 IEnumerable< object>
是 List< T>
),您根本不需要强制转换。)
The reason why you didn't find this error is because you used x as T
, where you should have been using a normal cast ((T)x
), see question 2139798. The resulting InvalidCastException
would have pointed you at your error. (In fact, if the type relationship were correct (i.e. if IEnumerable<object>
were a supertype of List<T>
), you wouldn't need a cast at all.)
要解决您的问题,请使您的方法通用,使其接受 IEnumerable< T>
而不是 IEnumerable< object>
,并完全跳过转换。
To solve your problem, make your method generic, so that it accepts an IEnumerable<T>
instead of an IEnumerable<object>
, and skip the cast completely.
public static void VerifyNotNullOrEmpty<T>(IEnumerable<T> theIEnumerable,
string theIEnumerableName,
string theVerifyingPosition) { ... }
这篇关于通用列表< T>作为IEnumerable< object>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!