How do I clear this list/array? Forms - c#

I am making a To Do program in windows forms where I want to save events, what day/hour they happen and the priority.
I am filling a listbox with information, then I want to start over and have a clean slate. The listbox looks cleared but once another input is made all the old ones show up as well. I think this is because I havent cleared the list/array.
I've tried using Array.Clear(), but I dont know whether to make a new method for it or put it in my InitalizeGUI(). I also don't know if I am clearing a list or an array as it is a list to start with but is converted to a string array.
class TaskManager
{
private List<Task> todo;
public TaskManager()
{
todo = new List<Task>();
}
public Task GetItem (int index)
{
if (!CheckIndex(index))
return null;
return todo[index];
}
public int Count
{
get { return todo.Count; }
}
public bool AddItem (Task itemIn)
{
bool ok = false;
if (itemIn != null)
{
todo.Add(itemIn);
ok = true;
}
return ok;
}
private bool CheckIndex (int index)
{
return(index >= 0) && (index < todo.Count);
}
public string [] ListToStringArray()
{
string[] taskArray = new string[Count];
for (int i = 0; i < Count; i++) taskArray[i] = todo[i].ToString();
return taskArray;
}
}
}
This is my Taskmanager class. Do i make a method to clear this list/array, and should it be made in TaskManager or Mainform?
I've tried all the ways I could from googling online but I can't figure it out.
Hopefully someone knows how to help!
Best regards

Add a new public method in TaskManager class that clears the 'todo' private variable.:
public void ClearList()
{
todo.Clear();
}
Call it when you need your list empty. Eg.: At the InitGui() method.

Related

How can I populate a string array with a parameter method C#

I am trying to populate a string array called "items" with a pre written method called "insert".
The project has pre written code "b.insert("apple");" etc etc and the method given is "public void insert(T item)". I have to write the code in this method to make the "insert" function work. I have to pass "item" into "items" array but my for loop simply gives me the output "milk" 10 times. Because of this, I know that "item" value is simply changing to the last string passed in the insert method. Would I have to write a nested for loop where "item" is a counter? In this case "item" cannot be a counter because it is a string type. Should I convert "item" into an array?
I'm not sure why such a seemingly simple task has me stumped by I've been at it for hours and at this point I just want to sort it out for the sake of sanity.
thanks in advance
class Program
{
static void Main(string[] args)
{
BoundedBag<string> b = new BoundedBag<string>("ShoppingList", 10);
b.insert("apple");
b.insert("eggs");
b.insert("milk");
Console.WriteLine(b);
Console.ReadKey();
}
}
public interface Bag<T> where T : class
{
void insert(T item);
string getName();
bool isEmpty();
}
public class BoundedBag<T> : Bag<T> where T : class
{
private string bagName; // the name of the bag
protected int size; // max size of the bag
private int lastIndex;
protected T[] items;
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
rnd = new Random();
items = new T[size];
}
public string getName()
{
return bagName;
}
public bool isEmpty()
{
return lastIndex == -1;
}
public bool isFull()
{
if(items.Length >= size)
{
return true;
}
else { return false;}
}
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
for (int i = 0; i < size; i++)
{
items[i] = item;
}
}
}
You only want to insert one item into your array on insert so you shouldn't have a loop at all. Use the lastIndex field to insert one item into the appropriate place in the array:
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
if(isFull())
{
throw new FullBagException();
}
items[++lastIndex] = item;
}
Unfortunately your isFull method is also broken and your isEmpty method won't work properly unless you change the constructor.
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
items = new T[size];
lastIndex = -1;
}
public bool isFull()
{
return lastIndex == size - 1;
}

C# unused Property crash my code

The Code prints different answer depending on debugging or not. What did i wrong?
class Program
{
static void Main(string[] args)
{
Feld feld = new Feld();
feld.Setze = 5;
Console.WriteLine(feld.Besetzt);
Console.Read();
}
}
public class Feld
{
public int figur;
public bool Besetzt { get => (figur != 0) ? true : false; }
public int Setze { set => figur = value; }
public int Nehmen { get { int cur = figur; figur = 0; return cur; } }
}
If i delet the last Property it work's but why?
To expand on the existing comments and answers: your Nehmen property has nasty side-effects:
public int Nehmen { get { int cur = figur; figur = 0; return cur; } }
every time the value is read, it resets itself to zero. This is a very bad idea - property get accessors should not have unexpected side-effects. Large parts of the tooling expect reading Nehmen to not do that, and the IDE / debugger will often try to help you understand your data by querying the properties to show you.
This means that when the debugger is trying to help you, it is actually resetting the values.
So: make Nehmen a method:
public int Nehmen()
{
int cur = figur;
figur = 0;
return cur;
}
The system expects methods to have side-effects, so does not invoke them to "help" you.
The only valid side-effects of property get accessors is to invoke lazy-loading / initialization side effects.
You must have the variable Nehmen in the Watch Window in Visual Studio... Or trying to access it in other way

With Statement in C# like that of AS3/GML

I'm making a game using Monogame, and I've been trying to figure out how to implement a function that acts similarly to AS3's and GML's with statement.
So far I have a system that works, but not entirely the way I want it to. I store my GameObjects in a Dictionary of Lists. This is so I can get to the specific type of object I want to access without having to loop through a list of ALL objects. The key used is the name of the type.
public static Dictionary<string, List<GameObject>> All =
new Dictionary<string, List<GameObject>>();
I access all of a specific type of object using AllOf. If a List containing that type exists in the Dictionary, it returns that List, else it returns an empty list.
public static List<GameObject> AllOf(Type type)
{
string key = type.Name;
if(All.ContainsKey(key))
{
return All[key];
}
return new List<GameObject>();
}
An example of how these are implemented
public override void Update(GameTime gameTime)
{
List<GameObject> list = Instance.AllOf(typeof(Dummy));
for(int i = 0; i < list.Count; i++)
{
list[i].Update(gameTime);
list[i].foo += bar;
}
}
But I'd rather use something similar to the AS3/GML with statement, which would also allow for other, non-member codes to be executed.
with(typeof(Dummy))
{
Update(gameTime);
foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
Is there a way to accomplish this? My end goal is just to make my code look a little cleaner, and make it easier to make a lot of changes without having to type out a for loop each time.
No such syntax exists in C#, but you can access methods within the for that have nothing to do with the collection:
public override void Update(GameTime gameTime)
{
List<GameObject> list = Instance.AllOf(typeof(Dummy));
for(int i = 0; i < list.Count; i++)
{
list[i].Update(gameTime);
list[i].foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
}
Note that you can also use foreach, which is a little cleaner if you don't need the indexer:
foreach(var item in list)
{
item.Update(gameTime);
item.foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
try
using(Object myObject = new Object()){
}
i think this might be what your looking to use?
I have a small solution for this use case. This may be a bit of a necropost, but it is a pretty neat solution. Additionally, I think all of the C# features that are required existed back when this question was asked.
You can do something very similar to the GML with(x){} by using some form of delegate as a parameter to a static method, and passing a lambda as that parameter. The function can even be genericised, and you can call it without the class name by the using static statement. You will need to explicitly provide the typed/named parameter, but it is possible. You would need to hook it up to your own types, but the general idea is:
namespace NiftyStuff {
public static class With {
public static void with<T>(Action<T> proc) where T : GameObj {
var typeName = typeof(T).Name;
foreach (var item in GameObj.AllOf(typeName)) { proc((T)item); }
}
}
public class GameObj {
private static Dictionary<string, List<GameObj>> All = new Dictionary<string, List<GameObj>>();
public static List<GameObj> AllOf(string name) {
return All.ContainsKey(name) ? All[name] : null;
}
public static void Add(GameObj foo) {
string typeName = foo.GetType().Name;
List<GameObj> foos = All.ContainsKey(typeName) ? All[typeName] : (All[typeName] = new List<GameObj>());
foos.Add(foo);
}
public float x, y, angle;
public GameObj() { x = y = angle = 0; }
public void Destroy() { AllOf(GetType().Name)?.Remove(this); }
}
public class Enemy : GameObj {
public float maxHealth, curHealth;
public Enemy() : base() { maxHealth = curHealth = 300; }
public Enemy(float health) : base() { maxHealth = curHealth = health; }
public bool Damage(float amt) {
if (curHealth > 0) {
curHealth -= amt;
return curHealth <= 0;
}
return false;
}
}
public class Pumpkin : GameObj {
public bool exists = false;
public Pumpkin() : base() { exists = true; }
public bool LookAt() { return (exists = !exists); }
}
}
Actually using the above code would work as follows:
using NiftyStuff;
using static NiftyStuff.With;
//...
with ((Enemy e) => {
if (e.Damage(50)) {
Log("Made a kill!"); // Whatever log function you have...
}
});
with ((Pumpkin p) => {
if (p.LookAt()) {
Log("You see the pumpkin");
} else {
Log("You no longer see the pumpkin");
}
});
While not exactly like GML's with statement, it would at least let you run code against all of the registered objects of some type.
One important note is that you can't destroy objects inside of a with this way (due to concurrent modification of a collection while iterating it). You would need to collect all objects to be destroyed, and then remove them from the list in All, typically in a game loop this is done at the end of a frame.
Hope this helps, despite being 2 years out of date.

Access array inside a constructor

This Is for homework.
I have googled this and searched within stackoverflow, but I can not seem to find the answer. Perhaps my terminology is incorrect.
I am learning TDD for a class and my C# skills are rusty and limited.
I am trying to write a stack class. When I try to initiate an array inside the constructor, the methods cannot access it.
I'm sure it is something simple that I am missing.
Here is the code what i have tried so far :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tdd_programmingTest
{
class Stack
{
int index = 0;
public Stack()
{
int[] items;
}
public void Push(int p)
{
items[index] = p;
index++;
}
public int Pop()
{
index--;
return items[index];
}
internal int IndexState()
{
return index;
}
}
}
I'm not looking for someone to write the code for me, just point me in the right direction. Thank you.
What you have here is a local variable:
public Stack()
{
int[] items;
}
It exits only inside of the Stack() constructor, and only for the lifetime of its execution.
You need to declare items as a field (member variable):
class Stack
{
private int index = 0;
private int[] items; // <-- move it here, and mark it private
public Stack()
{
}
// ...
}
But you have bigger problems. This is just a reference to an array which you haven't created yet.
So, you need to instantiate an array:
int[] items = new int[SIZE];
...but what size will you use? Once you create the array, it can not grow. You'll have to allocate a larger array and copy it, once you run out of space. This auto-self-expansion is how many ADT's work under the hood.
Speaking of running out of space, you'd better pay attention to your array's bounds in Push() and Pop()!
EDIT: So you need to specify a size. Just add a parameter to the constructor.
class Stack
{
private int index = 0;
private int[] items;
public Stack(int initialSize)
{
items = new int[initialSize];
}
public Stack() : Stack(100)
{
}
}
Put int[] items; outside of the constructor and add size parameter to the constructor to specify the size of items:
class Stack
{
int index = 0;
int[] items = new int[0];
public Stack(int size)
{
items = new int[size]; // initiate items with size
}
public void Push(int p)
{
items[index] = p;
index++;
}
public int Pop()
{
index--;
return items[index];
}
internal int IndexState()
{
return index;
}
}

Mutithreading with sequence

I have a main task that is spawning threads to do some work. When the work is completed it will write to the console.
My problem is that some of the threads that are created later will finish faster than those created earlier. However I need the writing to the console to be done in the same exact sequence as the thread was created.
So if a thread had completed its task, while some earlier threads had not, it has to wait till those earlier threads complete too.
public class DoRead
{
public DoRead()
{
}
private void StartReading()
{
int i = 1;
while (i < 10000)
{
Runner r = new Runner(i, "Work" + i.ToString());
r.StartThread();
i += 1;
}
}
}
internal class Runner : System.IDisposable
{
int _count;
string _work = "";
public Runner(int Count, string Work)
{
_count = Count;
_work = Work;
}
public void StartThread()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(runThreadInPool), this);
}
public static void runThreadInPool(object obj)
{
((Runner)obj).run();
}
public void run()
{
try
{
Random r = new Random();
int num = r.Next(1000, 2000);
DateTime end = DateTime.Now.AddMilliseconds(num);
while (end > DateTime.Now)
{
}
Console.WriteLine(_count.ToString() + " : Done!");
}
catch
{
}
finally
{
_work = null;
}
}
public void Dispose()
{
this._work = null;
}
}
There may be a simpler way to do this than I used, (I'm used to .Net 4.0).
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication5
{
class Program
{
public static readonly int numOfTasks = 100;
public static int numTasksLeft = numOfTasks;
public static readonly object TaskDecrementLock = new object();
static void Main(string[] args)
{
DoRead dr = new DoRead();
dr.StartReading();
int tmpNumTasks = numTasksLeft;
while ( tmpNumTasks > 0 )
{
Thread.Sleep(1000);
tmpNumTasks = numTasksLeft;
}
List<string> strings = new List<string>();
lock( DoRead.locker )
{
for (int i = 1; i <= Program.numOfTasks; i++)
{
strings.Add( DoRead.dicto[i] );
}
}
foreach (string s in strings)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
public class DoRead
{
public static readonly object locker = new object();
public static Dictionary<int, string> dicto = new Dictionary<int, string>();
public DoRead()
{
}
public void StartReading()
{
int i = 1;
while (i <= Program.numOfTasks )
{
Runner r = new Runner(i, "Work" + i.ToString());
r.StartThread();
i += 1;
}
}
}
internal class Runner : System.IDisposable
{
int _count;
string _work = "";
public Runner(int Count, string Work)
{
_count = Count;
_work = Work;
}
public void StartThread()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(runThreadInPool), this);
}
public static void runThreadInPool(object obj)
{
Runner theRunner = ((Runner)obj);
string theString = theRunner.run();
lock (DoRead.locker)
{
DoRead.dicto.Add( theRunner._count, theString);
}
lock (Program.TaskDecrementLock)
{
Program.numTasksLeft--;
}
}
public string run()
{
try
{
Random r = new Random();
int num = r.Next(1000, 2000);
Thread.Sleep(num);
string theString = _count.ToString() + " : Done!";
return theString;
}
catch
{
}
finally
{
_work = null;
}
return "";
}
public void Dispose()
{
this._work = null;
}
}
}
}
Basically, I store the string you want printed from each task into a dictionary where the index is the task#. (I use a lock to make accessing the dictionary safe).
Next, so that the main program waits until all the background threads are done, I used another locked access to a NumTasksLeft variable.
I added stuff into the callback for the Runner.
It is bad practice to use busy loops, so I changed it to a Thread.Sleep( num ) statement.
Just change numOfTasks to 10000 to match your example.
I pull the return strings out of the dictionary in order, and then print it to the screen.
I'm sure you could refactor this to move or otherwise deal with the global variables, but this works.
Also, you might have noticed I didn't use the lock in the command
tmpNumTasks = numTasksLeft;
That's threadsafe, since numTasksLeft is an int which is read atomically on 32-bit computers and higher.
I don't know much on C#, but the whole idea of multi-threading is that you have multiple thread executing independently and you can never know which one will finish earlier (and you shouldn't expect earlier thread to end earlier).
One workaround is, instead writing out the finish message in the processing thread, have the processing thread setup a flag somewhere (probably a list with no of elements = no of thread spawned), and have a separate thread print out the finish message base on the flags in that list, and report up to the position that previous flag is consecutively "finished".
Honestly I don't feel that reasonable for you to print finish message like this anyway. I think changing the design is way better to have such meaningless "feature".
Typically, such requirements are met with an incrementing sequence number, much as you have already done.
Usually, the output from the processing threads is fed through a filter object that contains a list, (or dictionary), of all out-of-order result objects, 'holding them back' until all results with a lower seqeuence-number have come in. Again, similar to what you have already done.
What is not necessary is any kind of sleep() loop. The work threads themselves can operate the filter object, (which would beed a lock), or the work threads can producer-consumer-queue the results to an 'output thread' that operates the out-of-order filter.
This scheme works fine with pooled work threads, ie. those without continual create/terminate/destroy overhead.

Categories

Resources