通用列表作为 IEnumerable
我正在尝试将 List 转换为 IEnumerable,这样我就可以验证不同的列表不为 null 或为空:
假设 myList 是一个 List < T> 。然后在调用者代码中我想要:
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 为空!为什么?
I'm trying to do cast a List to an IEnumerable, so I can verify that different lists are not null or empty:
Suppose myList is a List < T > . Then in the caller code I wanted:
Validator.VerifyNotNullOrEmpty(myList as IEnumerable<object>,
@"myList",
@"ClassName.MethodName");
The valdiating code would be:
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);
}
}
However, this doens't work. It compiles, but theIEnumerable is null! Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
List 实现了 IEnumerable 所以你不需要强制转换它们,你只需要让你的方法接受一个通用参数,如下所示:
你应该能够用以下方式调用它:
你还可以稍微改进实现:
List implements IEnumerable so you don't need to cast them, you just need to make it so your method accepted a generic parameter, like so:
You should just be able to call it with:
You could also improve the implementation slightly:
IEnumerable
您没有发现此错误的原因是因为您使用了
x as T
,而您应该使用普通的强制转换((T)x
),请参阅< a href="https://stackoverflow.com/questions/2139798/why-is-the-c-as-operator-so-popular">问题 2139798。生成的InvalidCastException
会指出您的错误。 (事实上,如果类型关系正确(即如果IEnumerable
要解决您的问题,请使您的方法通用,以便它接受
IEnumerable
而不是IEnumerable
IEnumerable<object>
is not a supertype ofIEnumerable<T>
, so it is not a supertype ofList<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.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 resultingInvalidCastException
would have pointed you at your error. (In fact, if the type relationship were correct (i.e. ifIEnumerable<object>
were a supertype ofList<T>
), you wouldn't need a cast at all.)To solve your problem, make your method generic, so that it accepts an
IEnumerable<T>
instead of anIEnumerable<object>
, and skip the cast completely.假设您的目标至少是框架 3.0:
使用扩展名转换为通用
IEnumerable
编辑:
无论如何,我建议您更改方法以获取纯 IEnumerable,例如:
并在方法内部使用 foreach 或
theIEnumerable.Cast
这样您不必每次都转换为
IEnumerable
Supposing you're targeting at least framework 3.0:
Cast to a generic
IEnumerable<object>
using extension:EDIT:
anyway I'd suggest you to change your method to get a pure IEnumerable like:
and inside the method check if empty using foreach or
theIEnumerable.Cast<object>().Count()
In this way you don't have to cast every time to
IEnumerable<object>