簡體   English   中英

System.linq.Enumerable命名空間的FirstOrDefault()方法拋出NullReferenceException

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM