Initializing string array for data reference [duplicate] - c#

This question already has answers here:
Meanings of declaring, instantiating, initializing and assigning an object
(2 answers)
Closed 6 years ago.
What I'm trying to do with this is save a list of reference keys for everything that is populating a listbox. There will be an unknown quantity of lines(users/"patients"). After saving the list, I want to be able to use the listbox index to find the corresponding key, and use that to move on to the next part.
public partial class PatientList : Window
{
HumanResources ListAllPatients;
List<PatientInformation> AllPatients;
string[] Usernames;
public PatientList()
{
InitializeComponent();
int i = 0;
string[] Usernames = new string[i];
ListAllPatients = new HumanResources();
AllPatients = ListAllPatients.PopPatientList();
foreach (PatientInformation PatientChoice in AllPatients)
{
Usernames[i] = PatientChoice.Username;
lboxPatients.Items.Add(string.Format("{0} {1}; {2}", PatientChoice.FirstName, PatientChoice.LastName, PatientChoice.Gender));
i += 1;
}
}
Here is the code for the button that moves you on to the next section
public void btnSelectPatient_Click(object sender, RoutedEventArgs e)
{
PatientInfo PatientInfoWindow = new PatientInfo();
PatientInfoWindow.Show();
//i = lboxPatients.SelectedIndex;
//UserFactory.CurrentUser = Usernames2[i];
this.Close();
}
My issue is this: I believe I've initialized a string array to do this, but VS keeps telling me it isn't assigned to, and will always remain null.
My question: How and where do I properly initialize a string array (or something better) in order to accomplish sending the key from PatientList() to btnSelectPatient?

You are not initializing the string[] field but a local variable in the constructor here:
string[] Usernames;
public PatientList()
{
InitializeComponent();
int i = 0;
string[] Usernames = new string[i];
You have to assign this array to the field:
public PatientList()
{
InitializeComponent();
int i = 0;
this.Usernames = new string[i];
But that doesn't make much sense currently because it's length is always 0.
Maybe you want this instead:
public PatientList()
{
InitializeComponent();
ListAllPatients = new HumanResources();
AllPatients = ListAllPatients.PopPatientList();
this.Usernames = new string[AllPatients.Count];
int i = 0;
foreach (PatientInformation PatientChoice in AllPatients)
{
Usernames[i] = PatientChoice.Username;
lboxPatients.Items.Add(string.Format("{0} {1}; {2}", PatientChoice.FirstName, PatientChoice.LastName, PatientChoice.Gender));
i += 1;
}
}

You have a few mistakes:
Your initializing a new local variable instead of the class-level variable because you declare it again (string[] userNames = ...
Your initializing an array of length 0. This will fail when you try to add items to position 1 and above.
My advice would be to use a List, as it's better suited for dynamic length lists and you don't need to keep track of the index yourself, it will automatically be added at the right index:
HumanResources ListAllPatients;
List<PatientInformation> AllPatients;
List<string> Usernames = new List<string>();
public PatientList()
{
InitializeComponent();
ListAllPatients = new HumanResources();
AllPatients = ListAllPatients.PopPatientList();
foreach (PatientInformation PatientChoice in AllPatients)
{
Usernames.Add(PatientChoice.Username);
lboxPatients.Items.Add(string.Format("{0} {1}; {2}", PatientChoice.FirstName, PatientChoice.LastName, PatientChoice.Gender));
}
}

Related

why I get repeated object from List<E> in C#?

this is my question function, I send the collection of data to the ShuffledList function in order to get one row at a time
private void nextQuestion_Question()
{
ql1 = ShuffleList(ql1);
currentQuestion_List = ql1.ElementAt(0);
//ql1.RemoveAt(0);
txtQ.Text = currentQuestion_List.text;
btnA.Text = currentQuestion_List.a;
btnB.Text = currentQuestion_List.b;
btnC.Text = currentQuestion_List.c;
btnD.Text = currentQuestion_List.d;
}
but this function some times it returns repeated objects
private List<E> ShuffleList<E>(List<E> inputList)
{
List<E> randomList = new List<E>();
Random r = new Random();
int randomIndex = 0;
while (inputList.Count>0)
{
randomIndex = r.Next(inputList.Count); //Choose a random object in the list
randomList.Add(inputList[randomIndex]); //add it to the new, random list
inputList.RemoveAt(randomIndex); //remove to avoid duplicates
}
return randomList; //return the new random list
}
note I'm try to make a multi choices game and it works well but some times repeat the same questions
please if you can help me to solve this issue
I think you problem in your repeatable shuffles. Try to store shuffled list once to prevent case when you generate the same question position twice during game session
bool listShuffled = false;
private void nextQuestion_Question()
{
if(!listShuffled){
listShuffled = true;
ql1 = ShuffleList(ql1);
}
currentQuestion_List = ql1.ElementAt(0);
//ql1.RemoveAt(0);
txtQ.Text = currentQuestion_List.text;
btnA.Text = currentQuestion_List.a;
btnB.Text = currentQuestion_List.b;
btnC.Text = currentQuestion_List.c;
btnD.Text = currentQuestion_List.d;
}

select randomly from string array without repetitions

Good day I have some problem regarding selecting a random string from my string array I am currently developing a guessing word game.
this is my string array:
string[] movie = {"deadpool", "batmanvssuperman", "findingdory", "titanic", "suicidesquad", "lordoftherings", "harrypotter", "jurassicpark", "hungergames", "despicableme" };
while this is the process in selecting a random string to my array, what should i do next, because I want to select the string not repeated.
e.g
when the program starts it will select a string then when i select random string again i want to not select the previous word that i've already selected previously.
string word = movie[r.Next(0, movie.Length)].ToUpper();
Thank you for response! Have a nice day.
Well, simply convert your array to list and shuffle it in random order :
var rand = new Random();
string[] movies = { "deadpool", "batmanvssuperman", "findingdory", "titanic", "suicidesquad", "lordoftherings", "harrypotter", "jurassicpark", "hungergames", "despicableme" };
List<string> randomMovies = movies.ToList();
for (int i = 0; i < movies.Length / 2; i++)
{
var randNum = rand.Next(i, randomMovies.Count);
var temp = randomMovies[randNum];
randomMovies[randNum] = randomMovies[i];
randomMovies[i] = temp;
}
Then you can just take random elements by :
var randomMovie = randomMovies.First();
randomMovies.Remove(randomMovie); // either remove it or use loop to iterate through the list
I sort of like to use Queue collection here :
var moviesQueue = new Queue<string>(randomMovies);
while (moviewQueue.Count > 0)
{
Console.WriteLine(moviewQueue.Dequeue());
}
P.S.
As suggested you don't really need to delete elements from randomMovie, you can save last used index in some field and use it later;
var lastIndex = 0;
var randomMovie = randomMovies[lastIndex++];
Just loop if it's been selected. This is untested code:
private string _last;
private string GetNonRepeatedMovie()
{
string selected = "";
do
{
selected = movie[r.Next(0, movie.Length)].ToUpper();
}
while (selected == this._last);
this._last = selected;
return selected;
}
This should work to select the initial string as well when the application starts.
If you need to keep a memory, convert your list to be a class that contains the name and a field of whether it has been chosen or not.
If you go through all of them, turn this semiphor off and begin again.
class GuessingName
{
public GuessingName(string name){Name = name;}
public string Name;
public bool chosen;
}
class RandomNamePicker{
private List<GuessingName> names;
public RandomNamePicker(){
names = new List<GuessingName>();
names.Add(new GuessingName("movie"));
}
string RandomPicker(){
if(names.All(c=>c.chosen))
names.ForEach(c=>c.chosen=false);
int r1 = r.Next(0, names.Length);
while(names[r1].chosen){
r1= r.Next(0,names.Length);
}
return names[r1].Name;
}
}

How can I add a TextBox to my form which is in an Array? [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
On start, I want my program to check services status from a list in an array and then add them to two new textboxs:
public string[] wantedServices = { "MSSQL$SQL", "SQLBrowser" };
public TextBox[] txtserviceStatus = new TextBox[2];
//Gets Service Status On Load
public void StartServiceStatus()
{
int i = 0;
ServiceController[] services = ServiceController.GetServices()
.Where(svc => wantedServices.Contains(svc.ServiceName))
.ToArray();
foreach (ServiceController sc in services)
{
txtserviceStatus[i].Text = sc.Status.ToString();
this.Controls.Add(txtserviceStatus[i]);
txtserviceStatus[i].Left = 0;
txtserviceStatus[i].Top = (i + 1) * 20;
i++;
}
}
When I step through the code, it only does the first line and doesn't break the rest within the foreach loop
Any advice would be greatly appreciated as I am still new to this and want to achieve 'good code'
Many Thanks
You're basically just creating an array of objects of the class TextBox, but afterwards you're using the objects without connecting any instance of the class to them. So, all you'll have to do is to just add txtserviceStatus[i] = new TextBox(); at the beginning of your loop, so that there would be an instance of the textbox to work with.
When you create the array txtserviceStatus = new TextBox[2] the values in that array are all null by default. You need to create the items in the array yourself:
public string[] wantedServices = { "MSSQL$SQL", "SQLBrowser" };
public TextBox[] txtserviceStatus;
//Gets Service Status On Load
public void StartServiceStatus()
{
txtserviceStatus = ServiceController.GetServices()
.Where(svc => wantedServices.Contains(svc.ServiceName))
.Select(sc => sc.Status.ToString())
.Select(CreateTextBox)
.ToArray();
txtserviceStatus.ForEach(this.Controls.Add);
}
private TextBox CreateTextBox(string text, int i) {
TextBox textBox = new TextBox();
textBox.text = text;
textBox.Left = 0;
textBox.Top = (i + 1) * 20;
return textBox;
}

NullReferenceException when assigning property of array item [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I want to create an array of my class Word. Here is the code:
public static void Main(string[] args)
{
Word[] Wörter = new Word[5];
Wörter[0]._Word_ = "Hallo";
Wörter[1]._Word_ = "Flugzeug";
Wörter[2]._Word_ = "Automobil";
Wörter[3]._Word_ = "Musikanlage";
Wörter[4]._Word_ = "Steuerung";
}
public class Word
{
private string _Word;
private int _counter;
public string _Word_
{
get
{
return _Word;
}
set
{
_Word = value;
}
}
public int _counter_
{
get
{
return _counter;
}
set
{
_counter = 0;
}
}
}
I always get a System.NullReferenceException in this line
Wörter[0]._Word_ = "Hallo";
If I call the an instance of my class(without array), everything works fine. I think I got a problem with the array. Maybe is using an array in this situation not the best think to do. Thank you for helping!
You only istantiate the array but not the elements
Word[] Wörter = new Word[5];
Wörter[0] = new Word { _Word_ = "Hallo" };
and so on...
The problem is that you're creating an array, but that array contains empty references to start with - you're never creating any instances of Word. You want something like:
Word[] Wörter = new Word[5];
Wörter[0] = new Word();
Wörter[0]._Word_ = "Hallo";
// etc
However, you can reduce the code to achieve the same effect using object initializers:
Word[] Wörter = new Word[5];
Wörter[0] = new Word { _Word_ = "Hallo" };
...
And then you can use an array initializer to do the whole thing in one statement:
Word[] Wörter =
{
new Word { _Word = "Hallo" },
new Word { _Word_ = "Flugzeug" },
new Word { _Word_ = "Automobil" },
new Word { _Word_ = "Musikanlage" },
new Word { _Word_ = "Steuerung"}
};
The next step in my view would be to start following .NET naming conventions, calling your properties Text and Counter (you can't call the property Word as that's the name of the class), using automatically implemented properties to reduce cruft further, and then adding a constructor taking the initial value of the property in the constructor:
public class Word
{
public string Text { get; set; }
public int Counter { get; set; }
public Word(string text)
{
Text = text;
}
}
Word[] words =
{
new Word("Hallo"),
new Word("Flugzeug"),
new Word("Automobil"),
new Word("Musikanlage" )
new Word("Steuerung")
};
Doesn't that look better? :)
You might also want to make the Text property read-only. Until C# 6 lands that means either keeping a private setter or using a "manually implemented" property, but in C# 6 you'll be able to write:
public string Text { get; }
and just assign it in the constructor.
Additionally, you need to think about whether you really need an array at all. Often using a List<T> offers significantly more flexibility.
Try this way:
Word[] Wörter = new Word[5];
for (int i = 0; i < 5; i++)
Wörter[i] = new Word();
Wörter[0]._Word_ = "Hallo";
Wörter[1]._Word_ = "Flugzeug";
Wörter[2]._Word_ = "Automobil";
Wörter[3]._Word_ = "Musikanlage";
Wörter[4]._Word_ = "Steuerung";

The type initializer for Form1 threw an exception

So I am somewhat new to coding C# and exception handling is not one of my strengths. I am trying to write a hangman-style game, but am running into an issue when trying to execute the program. I receive an unhandled exception message with the text "The type initializer for (filename)Form1 threw an exception." I'm not really sure how to find where the error is originating from, other than I receive the message in my Program.cs file. I have looked around on here for similar problems, but the answers are very specific to the individual problem. In my case, my code is as follows:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//set label to blank
answerLabel.Text = "";
//loop through each element in the array
for (int i = 0; i < guessThis.Length; i++)
{
//get each element as a question mark
string unknown = "?";
//add each element as a "?" to the label
answerLabel.Text += unknown;
}
}
/*----------------------------------------------------------------------------------------------------------------------------------------------*/
//initialize array from currentAnswer string
public static char[] guessThis = currentAnswer.ToCharArray();
//create array of strings for answers
public static string[] randomAnswers = new string[10]{"beach", "sword", "sushi", "rat", "joy", "summer", "animal", "baseball", "toyota", "red"};
//set up random
public static Random rand1 = new Random();
//pick a random word from the answers array
public static string currentAnswer = randomAnswers[rand1.Next(0, randomAnswers.Length)];
/*----------------------------------------------------------------------------------------------------------------------------------------------*/
//guess button
private void button1_Click(object sender, EventArgs e)
{
//set a bool for if the user input contains only letters
bool containsLetter = textBox1.Text.Any(x => char.IsLetter(x));
//checks if textbox length is not 1 character
if (textBox1.Text.Length != 1)
{
//display error
MessageBox.Show("Please enter one letter", "Error");
}
//if user input is not a letter
else if (containsLetter != true)
{
//display error
MessageBox.Show("Please enter only letters", "Error");
}
//if all conditions satisfied
else
{
//check if char array contains the user input
if (guessThis.Contains(Convert.ToChar(textBox1.Text)))
{
//get index of any element that contains the userinput
var getIndex = Array.FindIndex(guessThis, row => row.Equals(textBox1.Text));
//set up another array with the values from the label
char[] unknownAnswer = answerLabel.Text.ToCharArray();
//insert user input into the proper index of the char array
unknownAnswer[getIndex] = Convert.ToChar(textBox1.Text);
//update the label
answerLabel.Text = unknownAnswer.ToString();
}
}
}
}
Thanks for any help offered.
The C# references of Static Field Initializations says
The static field variable initializers of a class correspond to a
sequence of assignments that are executed in the textual order in
which they appear in the class declaration. If a static constructor
(Section 10.11) exists in the class, execution of the static field
initializers occurs immediately prior to executing that static
constructor. Otherwise, the static field initializers are executed at
an implementation-dependent time prior to the first use of a static
field of that class.
So in your code you have these statics fields
public static char[] guessThis = currentAnswer.ToCharArray();
public static string[] randomAnswers = new string[10]{"beach", "sword", "sushi", "rat", "joy", "summer", "animal", "baseball", "toyota", "red"};
public static Random rand1 = new Random();
public static string currentAnswer = randomAnswers[rand1.Next(0, randomAnswers.Length)];
guessThis is intialized from currentAnswer, but at that point, currentAnswer is still not valid because it is initialized from randomAnswers still not initialized
So you could just flip the order of initialization as follow
public static Random rand1 = new Random();
public static string[] randomAnswers = new string[10]{"beach", "sword", "sushi", "rat", "joy", "summer", "animal", "baseball", "toyota", "red"};
public static string currentAnswer = randomAnswers[rand1.Next(0, randomAnswers.Length)];
public static char[] guessThis = currentAnswer.ToCharArray();
But I am really wondering why you need these static fields. Do you need them globally available for every other instance of your form? If not keep in mind that this kind of pattern is really unclear for every future reader of this code, you and me included
From the partial context above, your code could also written without using any static variable, just standard global instance level variables.
private Random rand1 = new Random();
private string[] randomAnswers = new string[10]{"beach", "sword", "sushi", "rat", "joy", "summer", "animal", "baseball", "toyota", "red"};
private char[] guessThis;
private string currentAnswer;
public Form1()
{
InitializeComponent();
currentAnswer = randomAnswers[rand1.Next(0, randomAnswers.Length)];
guessThis = currentAnswer.ToCharArray();
//set label to blank
answerLabel.Text = "";
//loop through each element in the array
for (int i = 0; i < guessThis.Length; i++)
{
//get each element as a question mark
string unknown = "?";
//add each element as a "?" to the label
answerLabel.Text += unknown;
}
}

Categories

Resources