1

I am trying to change a value of csv file in C# console. First I load the content of the csv file into the code. Then I change a value and try to save it.

This is the content of the csv before (and sadly after) execution:

1;Geg;17
2;Geg;17
3;Geg;17

During runtime the values change into: new Values

But somehow they do not get saved into the csv file.

This is my code:

main class:

     using System;
     using System.Collections.Generic;
     using System.Data;
     using System.IO;
     using System.Text.RegularExpressions;
     
     namespace csvtest
     {
         class Program
         {
             static void Main(string[] args)
             {
                 Tabelle tab = new Tabelle();
                 foreach (Employees e in tab.getAll())
                 {   
                     Console.WriteLine(e);
                 }
     
                 tab.updating(1, "fafdsdsf", 323);
     
             }
             
         }
     }

Tabelle class:

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Threading.Tasks;
     using System.IO;
     
     namespace csvtest
     {
         class Tabelle
         {
             private List<Employees>liste;
             public Tabelle()
             {
                 
                 liste = new List<Employees>();
                 string[] rows = File.ReadAllLines(@"C:\Users\rbc\Desktop\csvtest\csvtest\obj\test.csv");
                 foreach (string row in rows)
                 {
                     string[] information = row.Split(';');
                     int number = int.Parse(information[0]);
                     string name = information[1];
                     double salary = double.Parse(information[2]);
     
                     liste.Add(new Employees { Number = number, Name = name, Salary = salary });
                 }
             }
             public  Employees[] getAll()
             {
                 return liste.ToArray();
                 
             }
             public void adding(int number, string name, double salary)
             {
                 liste.Add(new Employees { Number = number, Name = name, Salary = salary });
             }
             public void updating(int number, string name, double salary)
             {
                 foreach (Employees e in liste)
                 {
                     if (e.Number == number)
                     {
                         e.Name = name;
                         e.Salary = salary;
                     }
                 }
             }
             ~Tabelle()
             {
                 string[] information = new string[liste.Count];
                 for (int i = 0; i<liste.Count; i++)
                 {
                     information[i] = liste[i].Number + ";" + liste[i].Name + ";" + liste[i].Salary;
                 }
                 File.WriteAllLines(@"C:\Users\rbc\Desktop\csvtest\csvtest\obj\test.csv", information);
     
             }
         }
     }
     

Employees class:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace csvtest
 {
     class Employees
     {
         public int Number { get; set; }
         public string Name { get; set; }
         public double Salary { get; set; }
 
 
         public override string ToString()
         {
             return Number + "|" + Name + "|" + Salary;
         }
     }
 }

I have no idea what the problem is. I appreciate any ideas or hints.

Thanks a lot in advance for your help!!

5
  • 1
    Nothing immediately obvious is wrong; I would recommend that you run the program using the debugger and single-step through it to see if all the steps are being executed as you expected. The program and the data set are not so large so this can easily be done. Commented Aug 25, 2021 at 11:44
  • 4
    it's extemely bad to do anything in the finalizer (~Tabelle) except cleaning up. writing your data to a file is not cleaning up. move your code out of the finalizer - trust me, you don't need it. if you need to write exactly when you're done with the object, at least use IDisposable instead. also: please don't roll your own CSV. there's enough libraries around that handle that stuff better than you can imagine. Commented Aug 25, 2021 at 11:46
  • 3
    Probably this learn.microsoft.com/en-us/dotnet/csharp/programming-guide/… is relevant for your problem: The programmer has no control over when the finalizer is called; the garbage collector decides when to call it. The garbage collector checks for objects that are no longer being used by the application. If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object. So it looks like your finalizer is not called immediately, but maybe will be later... Commented Aug 25, 2021 at 11:47
  • 2
    I agree with @FranzGleichmann, it would be also a good thing to extract a Save() method and call it as per your needs. Commented Aug 25, 2021 at 11:47
  • 1
    Writing dirty buffers back to their source could be considered cleaning up, although I agree that making a separate Save() method would be more reliable here. Commented Aug 25, 2021 at 11:49

1 Answer 1

1

As other people suggested here, it's true that the developer hasn't control over when the finalizer is called. The garbage collector decides when to free the memory.

But, you should look at Dispose. If you implement IDisposable, and dispose of your object, then the code in Dispose will run.

First of all, your class should implement the above interface

class Tabelle : IDisposable

Then you need to wrap your code from destructor with the Dispose() method.

public void Dispose()
{
    string[] information = new string[liste.Count];
    for (int i = 0; i < liste.Count; i++)
    {
       information[i] = liste[i].Number + ";" + liste[i].Name + ";" + liste[i].Salary;
    }
    File.WriteAllLines(@"data.txt", information);
    GC.SuppressFinalize(this);
}

Also, don't forget to use using keyword when creating your class.

 using (Tabelle tab = new Tabelle())
 {
       foreach (Employees e in tab.getAll())
       {
           Console.WriteLine(e);
       }

       tab.updating(1, "fafdsdsf", 323);
 }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.