![](/img/trans.png)
[英]Why there is no SelectToArray method in System.Linq.Enumerable
[英]FirstOrDefault() method of System.linq.Enumerable namespace throwing NullReferenceException
我有一个用户定义的对象类型的静态只读集合,它初始化如下。
private static readonly List<MyClass> obj = new List<MyClass>();
另一个公用实用程序方法填充此集合并返回集合。
public static List<MyClass> GetMyClasses(){
// some code for DB calls goes here
// in a loop based on recordset, i fill the collection like below
obj.Add(new MyClass(){// my class property settings based on DB values});
// finally return the collection
return obj;
}
我在下面的行'ac'对象上得到'对象引用未设置为对象的实例'。
var cl = TestClass.GetMyClasses().FirstOrDefault(ac => ac.name == "myname")
我想知道为什么'ac'对象在这里是NULL,即使我们的集合是空的,因为MSDN FirstOrDefault如果找不到匹配则应该为引用类型返回NULL。
有人可以帮我理解我在这里缺少的东西吗? 在今天开始抛出异常之前,相同的代码在几个月内完美运行。 即使在今天,相同的代码在其他服务器上运行良好也没有问题。
出于安全原因,我无法发布整个异常堆栈跟踪,但它指向IL代码下方
在System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable`1 source,Func`2谓词)
使用示例类似的问题代码更新问题。
public static class DemoDataAccess
{
private static readonly List<MyTestClass> classes
= new List<MyTestClass>();
public static IList<MyTestClass> GetMyClasses()
{
using (var cnn = new SqlConnection(@"connection string goes here"))
{
cnn.Open();
using (var cmd = new SqlCommand("SP Name", cnn))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
classes.Add(new MyTestClass()
{
Id = Convert.ToInt32(rdr["id"]),
Name = Convert.ToString(rdr["name"])
});
}
}
}
}
return classes;
}
}
public class MyTestClass
{
public int Id { get; set; }
public string Name { get; set; }
}
在线下方抛出一致异常,堆栈跟踪指向'ac'实例。
var obj = DemoDataAccess
.GetMyClasses()
.FirstOrDefault(ac => ac.Name == "something");
我想知道为什么'ac'对象在这里是NULL,即使我们的集合是空的,因为MSDN FirstOrDefault如果找不到匹配则应该为引用类型返回NULL。
这表明GetMyClasses()
返回一个集合,该集合在与谓词匹配的任何元素之前具有null元素。 这与集合为空是不一样的。
检查一下:
int nullElements = TestClass.GetMyClasses().Count(ac => ac == null);
我强烈怀疑你会发现nullElements
不为零。
如果这不是问题,那么你应该努力提供一个简短但完整的程序,你可以发布。 您不需要发布真实代码 - 只是显示相同问题的代码。 看到这样的代码我会感到非常惊讶 - 我觉得你在某种程度上更有可能在开始时得到一个null元素,这肯定会解释你所看到的异常。
另外, ac
不是一个对象 - 它是一个变量(一个lambda表达式参数)。 区分对象,变量和引用非常重要。 对象永远不能为null - 变量的值可以是。
首先是明显的东西:你正在访问
...ac.name == "..."
此时,如果ac为null,您将获得空指针异常。 这也意味着,由于某种原因,您的集合包含NULL元素。
现在,根据您复制的代码,不可能存在NULL元素,这不是完整的代码,并且存在将NULL插入列表的故障,或者您的应用程序中必须存在其他地方更改集合并将元素设置为null。
:编辑:在填充和读取数组之间是否有任何异步或并行代码执行?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.