1

Here are my classes:

public class Type_WorkSched
{
    public string EmployeeID { get; set; }
    public string RecordID { get; set; }
    public Type_Schedule[] Schedule { get; set; }
}

public class Type_Schedule
{
    public string Days { get; set; }
    public string TimeIn_AM { get; set; }
    public string TimeOut_AM { get; set; }
    public string TimeIn_PM { get; set; }
    public string TimeOut_PM { get; set; }
}

I want to store an array of MySchedule into an object MyWorkSched.

But I get only the last value of the array.

GV_WorkSched is the name of the datagrid.

Type_Schedule[] MySchedule = new Type_Schedule[GV_WorkSched.RowCount-1];
Type_WorkSched MyWorkSched = new Type_WorkSched();
           
MyWorkSched.EmployeeID = Txt_EmployeeID.Text;
MyWorkSched.RecordID = Txt_RecordNumber.Text;

for (int i = 0; i < GV_WorkSched.RowCount-1; i++)
{
    MySchedule[i] = new Type_Schedule();
    MySchedule[i].Days = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "Days"));
    MySchedule[i].TimeIn_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_AM"));
    MySchedule[i].TimeOut_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_AM"));
    MySchedule[i].TimeIn_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_PM"));
    MySchedule[i].TimeOut_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_PM"));
                
    MyWorkSched.Schedule = new Type_Schedule[] { MySchedule[i] };
}

Or is there another way to do it?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
sim
  • 23
  • 7

4 Answers4

1

You should do it as below

        Type_Schedule[] MySchedule = new Type_Schedule[GV_WorkSched.RowCount];
        Type_WorkSched MyWorkSched = new Type_WorkSched();
       
        MyWorkSched.EmployeeID = Txt_EmployeeID.Text;
        MyWorkSched.RecordID = Txt_RecordNumber.Text;

        for (int i = 0; i < GV_WorkSched.RowCount; i++)
        {
            MySchedule[i] = new Type_Schedule();
            MySchedule[i].Days = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "Days"));
            MySchedule[i].TimeIn_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_AM"));
            MySchedule[i].TimeOut_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_AM"));
            MySchedule[i].TimeIn_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_PM"));
            MySchedule[i].TimeOut_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_PM"));
        }

        MyWorkSched.Schedule = MySchedule;
Mohammad Ali
  • 551
  • 7
  • 17
0

Your problem is on this line

MyWorkSched.Schedule = new Type_Schedule[] { MySchedule[i] }

At the end of each iteration, you create a new array, with only one value in it (the latest). When you get out of it this is the only one that remains.

Try the following. I totally removed the intermediate array as I think it was part of the confusion.


    Type_WorkSched MyWorkSched = new Type_WorkSched();
    MyWorkSched.Schedule = new Type_Schedule[GV_WorkSched.RowCount];
           
    MyWorkSched.EmployeeID = Txt_EmployeeID.Text;
    MyWorkSched.RecordID = Txt_RecordNumber.Text;
    for (int i = 0; i < GV_WorkSched.RowCount-1; i++)
    {
         MyWorkSched.Schedule[i] = new Type_Schedule();
         MyWorkSched.Schedule[i].Days = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "Days"));
         MyWorkSched.Schedule[i].TimeIn_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_AM"));
         MyWorkSched.Schedule[i].TimeOut_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_AM"));
         MyWorkSched.Schedule[i].TimeIn_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeIn_PM"));
         MyWorkSched.Schedule[i].TimeOut_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(i, "TimeOut_PM"));
  }
Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • wont work man.. cus i want a return value of ```MyWorkSched``` not ```MySchedule``` thats why i want to store the value of ```MySchedule``` to ```MyWorkSched```. – sim Sep 09 '20 at 06:15
  • I'm saving directly in `MyWorkSchedule`, return it and it'll have the values in `MyWorkSchedule.Schedule` – Athanasios Kataras Sep 09 '20 at 06:19
  • it returns this: System.NullReferenceException: 'Object reference not set to an instance of an object.' – sim Sep 09 '20 at 06:23
  • Which line? Btw I changed the array init to the correct size, which is `Count`, not `Count-1` – Athanasios Kataras Sep 09 '20 at 06:28
0
        Type_Schedule[] MySchedule = new Type_Schedule[GV_WorkSched.RowCount-1];
                    Type_WorkSched MyWorkSched = new Type_WorkSched();
                   
                        MyWorkSched.EmployeeID = Txt_EmployeeID.Text;
                        MyWorkSched.RecordID = Txt_RecordNumber.Text;
                   
    MyWorkSched.Schedule = new Type_Schedule[] { 
    new Type_Schedule {
                    Days = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(GV_WorkSched.RowCount-1, "Days")),
                    TimeIn_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(GV_WorkSched.RowCount-1, "TimeIn_AM")),
                    TimeOut_AM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(GV_WorkSched.RowCount-1, "TimeOut_AM")),
                    TimeIn_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(GV_WorkSched.RowCount-1, "TimeIn_PM")),
                    TimeOut_PM = Convert.ToString(GV_WorkSched.GetRowCellDisplayText(GV_WorkSched.RowCount-1, "TimeOut_PM"))
                 };
     };
Since you are any ways trying to fetch the last value only why do you want to reassign a new Type_Schedule array every time in the loop.Avoid the loop  and if  you want to store the entire schedule data then use a loop.
MyWorkSched.Schedule = new Type_Schedule[] { MySchedule[i] };// this line if inside the loop at the end of the loop will give the same result as above 
-1

I suggest to use List<> instead. First, redeclare your type as

public class Type_WorkSched
{
    public string EmployeeID { get; set; }
    public string RecordID { get; set; }
    public List<Type_Schedule> Schedule { get; set; }

    // In case you really need it as Array
    public Type_Schedule[] ScheduleAsArray()
    {
        return Schedule.ToArray();
    }
}

Second, iterate your grid in foreach way

foreach (DataGridViewRow row in GV_WorkSched.Rows)
{

    var schedule = new Type_Schedule
    {
        Days = row.Cells["Days"].Value.toString(),
        //...
    };

    MyWorkSched.Schedule.Add(schedule);
}
Roman Ryzhiy
  • 1,540
  • 8
  • 5
  • You are using more space and time for the conversion. It's always better to use arrays when you have a fixed size and it's certainly better to avoid conversions. – Athanasios Kataras Sep 09 '20 at 06:37
  • @AthanasiosKataras No I am not. As we know from .Net source code, List is stored, operated and optimized as Array anyway, and its conversion costs nothing. – Roman Ryzhiy Sep 09 '20 at 06:41
  • Of course it does: https://stackoverflow.com/questions/1147497/c-sharp-listt-toarray-performance-is-bad It does not have `bad` befrormance but it still iterates and copies the items from one collection to the other. – Athanasios Kataras Sep 09 '20 at 06:51
  • @AthanasiosKataras No, it does not iterate anything. Array.Copy (in your reference) is "equivalent to the standard C/C++ function memmove" https://learn.microsoft.com/en-us/dotnet/api/system.array.copy?redirectedfrom=MSDN&view=netcore-3.1#System_Array_Copy_System_Array_System_Array_System_Int32_ – Roman Ryzhiy Sep 09 '20 at 07:17
  • From your link: This method is an O(n) operation, where n is length. As is iterating and copying from one list to an array. So the costs nothing part is not true. It does cost an O(n). If it did cost O(1) I would agree with you that it is negligible, but that's not the case. It would also render arrays useless if you think about it wouldn't it? – Athanasios Kataras Sep 09 '20 at 07:32
  • @AthanasiosKataras I performed a diagnostics. On my configuration (i7 16G etc) List.ToArray() for 1 million entries performs in 1 millisecond, for 1000 is in 0.0117 milliseconds. I stick to the point it is negligible. – Roman Ryzhiy Sep 09 '20 at 08:01
  • O(n) is never negligible, though I concede that with today's standards it won't take much. It's not a no-cost solution by any means though, and you'd get about the same result if you just iterated and assigned. You did also allocate twice as much space for the reference types (if it were value types it'd be worse) and kept them both. That's why it's a bad practice. It might not do much harm here, but correct coding practices help avoid problems in the long run in other situations too. Just ask yourself. When would you use an array over a list. If the answer is never, then open PR with MS. – Athanasios Kataras Sep 09 '20 at 08:10
  • By the way, the `Type_Schedule[].ToList()` (I believe it is the 1st operation that the OP will do with the array) for 1M records performs 3 times longer. – Roman Ryzhiy Sep 09 '20 at 08:12
  • This is just an assumption. If that were the case, then he wouldn't need the conversion either way and the answer would indeed be to use a list. – Athanasios Kataras Sep 09 '20 at 08:13