【发布时间】:2019-09-04 00:29:10
【问题描述】:
有一个进程从字符串中获取正在运行的进程。
Dim processName As String = "foo"
Dim qProcess As IEnumerable(Of Process) = Process.GetProcesses.Where(Function(x) x.ProcessName.ToUpper = processName.ToUpper())
Return qProcess.FirstOrDefault() IsNot Nothing
在极少数情况下,Where 方法中会发生空引用异常。
堆栈跟踪:
NullReferenceException: Object reference not set to an instance of an object
at NameSpace.MyClass._Closure$__1-0._Lambda$__0(Process x)
at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at NameSpace.MyClass.MyMethod()
我第一次体验到 qProcess 变成了 Nothing。 什么时候出现这个异常? 这似乎是在重新启动机器后发生的。
附言 如何在 linq 表达式中命名变量名? 我前缀“q”(例如qProcess)
谢谢。
【问题讨论】:
-
请不要添加无关标签。
-
您似乎正在尝试执行不区分大小写的比较,但您以错误的方式进行。如果您以正确的方式进行操作,那么
Strings之一是否为Nothing就无关紧要了。Function(x) String.Equals(x.ProcessName, processName, StringComparison.CurrentCultureIgnoreCase). -
Return Process.GetProcesses.FirstOrDefault(Function(p) p.ProcessName.Equals(processName, StringComparison.CurrentCultureIgnoreCase)) IsNot Nothing -
@Jimi,如果
ProcessName是Nothing,那仍然会抛出NullReferenceException。您需要调用String.Equals的Shared重载以避免在不存在的实例上调用实例方法。你可以切换属性和局部变量:processName.Equals(p.ProcessName. -
@Jimi,我同意调用
FirstOrDefault并传递谓词比调用Where和FirstOrDefault更好,但是根据问题中的代码,还有更好的方法。如果您实际上不需要匹配的对象,则只需调用Any:Return Process.GetProcesses().Any(Function(p) String.Equals(p.ProcessName, processName, StringComparison.CurrentCultureIgnoreCase))。