我正在 Windows 表單中的一個學校專案中作業,我們正在創建一個動物注冊表。我有一個 Animal 類,其中動物物件是使用屬性 Id、Name、Age、Gender 和 Friendly 創建的。我還有一個 AnimalManager 類,它處理一個串列,通過它可以添加更多的動物。在運行時,當用資訊填寫適當的框并按下添加動物按鈕時,資訊應該添加到串列視圖中的一行(任務的重要部分。當我可以將它顯示在串列框)。
當我將我的資訊列印到一個串列框時,我只是將一個帶有適當資訊的字串public string AnimalInformation()從 Animal 類發送到 AnimalManager,后者編譯了一個陣列并將其發送到 Form1 以進行列印。由于我想在串列視圖中顯示它,我想我應該AnimalInformation()改為陣列,以便在通過 AnimalManager 后得到一個 2D 陣列,就像它在列印時顯示一樣。但是,我收到例外訊息System.NullReferenceException: 'Object reference not set to an instance of an object。在我的 AnimalManager 中運行程式并嘗試添加動物時。
這是 Animal 類中的方法:
public string[] AnimalInformation()
{
string[] strOut = { id, name, age.ToString(), gender.ToString(), FriendlyStr()};
return strOut;
}
這是 AnimalManager 類中的方法:
public string[][] GetAnimalInfoArray()
{
string[][] animals = new string[animalList.Count][];
for(int i = 0; i < animalList.Count; i )
{
Animal animal = animalList[i];
for(int j = 0; j < animal.CountAnimalInfo(); j )
{
string[] info = animal.AnimalInformation();
animals[i][j] = info[j];
}//here comes the exception
}
return animals;
}
而且由于我對 listview 不太熟悉(閱讀:一點也不熟悉),這是我撰寫的回圈,用于在我的UpdateGUI()方法中將其全部列印到 listview 中,以防這是造成問題的原因:
if (manager.Count() > 0)
{
foreach(string[] row in manager.GetAnimalInfoArray())
{
foreach(string item in row)
lvwAnimals.Items.Add(item);
}
}
我已經在這幾個小時了,不知道怎么了上升或下降了。我什至走在正確的軌道上嗎?我必須完全重做這個嗎?在大括號之后收到錯誤訊息我做錯了什么?
uj5u.com熱心網友回復:
第一個問題是您正在創建一個陣列陣列,但沒有在陣列中分配陣列......這有點令人困惑,但這是行:
string[][] animals = new string[animalList.Count][];
animals是一個陣列string[]。此時,animals陣列中的每個元素都是空的,而不是陣列。您遇到問題的地方是:
animals[i][j] = info[j];
此時animals[i]未初始化 ( null),因此沒有陣列供您使用j.
這個問題有很多解決方案,但最直接的方法是將呼叫的結果簡單地分配給AnimalInformation陣列槽并完成它:
public string[][] GetAnimalInfoArray()
{
string[][] animals = new string[animalList.Count][];
for(int i = 0; i < animalList.Count; i )
animals[i] = animalList[i].AnimalInformation();
return animals;
}
如果您可以使用 LINQ,還有一個更簡單的選項:ToArray().
public string[][] GetAnimalInfoArray()
=> animalList.Select(a => a.AnimalInformation()).ToArray();
關于其余代碼的一些注釋...
您的內部回圈呼叫CountAnimalInfo()和AnimalInformation()為資訊陣列中的每個專案。那是您呼叫這兩種方法的 5 次,每次至少創建一個陣列(我假設您不是AnimalInformation()從內部呼叫CountAnimalInfo(),如果您是,那么每個專案都有兩個陣列)。如果您必須回圈,最好簡單地呼叫一次并使用結果陣列進行回圈。
for (int i = 0; i < animalList.Count; i )
{
var info = animalList[i].AnimalInformation();
animals[i] = new string[info.Length];
for (int j = 0; j < info.Length; j )
animals[i][j] = info[j];
}
You're spreading what appears to be display code across several methods and classes. While there are times when it's useful to be able to override things in sub-classes, it's generally preferable (in my experience at least) to have the display code in one place: a single method or tightly coupled group of methods in a single class. An Animal doesn't need to know how it is being displayed, it just needs to present properties that other code can use. Your AnimalManager class probably doesn't need to act as go-between for your display code either, it's up to the display code to figure out how things should look. Try this:
foreach (var animal in manager.animalList)
{
lvwAnimals.Items.Add(animal.id);
lvwAnimals.Items.Add(animal.name);
lvwAnimals.Items.Add(animal.age.ToString());
lvwAnimals.Items.Add(animal.gender.ToString());
lvwAnimals.Items.Add(animal.FriendlyStr());
}
通過這種方式,您將“顯示”問題與非顯示類分開,讓他們更專注于自己的作業。額外的好處是,以后除錯的代碼行數要少得多。
uj5u.com熱心網友回復:
我知道這不能直接回答,JeremyLakeMan 評論了您目前遇到問題的原因。但這是我會做的
給定一個名為 animalList 的 IEnumerable 動物(您已經擁有)
假設動物看起來像這樣
public class Animal{
public string ID;
public String Name;
public int Age;
}
現在
foreach(var animal in animals)
{
lvwAnimals.Items.Add(animal.ID);
lvwAnimals.Items.Add(animal.Name);
lvwAnimals.Items.Add(animal.Age.ToString());
}
就是這樣,不需要整個 GetAnimalInfoArray
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/433992.html
