Code below.
I completely understand reference vs value types. [correction, I do not completely understand reference vs value types.]
Today I ran into something odd.
I declare a datatable class var and initialize it as null.
I create function: GetAutoAllocationResult(in int, datatable, out string)
I pass pass the datatable class var to the function.
I make some conditional changes inside a TRY/CATCH block.
I return from the function.
The datatable does not retain changes from within the function.
If I use the OUT keyword in the function signature for the datatable, it retains changes.
What?
DataTable auto_allocation_result = null;
// ...
// get the data from the stored procedure return
string auto_allocation_query_result_message = string.Empty;
bool is_auto_allocation_result_query_successful = false;
is_auto_allocation_result_query_successful = GetAutoAllocationResult(auto_allocation_record_uid,
auto_allocation_result, out auto_allocation_query_result_message);
//...
private bool GetAutoAllocationResult(in int p_auto_allocate_record_uid, DataTable p_return_data, string p_message)
{
bool is_successful = false;
p_return_data = new DataTable();
p_message = string.Empty;
string sql = some select statement
SqlCommand sc = new SqlCommand();
sc.Connection = some sql connection
sc.CommandText = sql;
// add parameters
SqlParameter sqlparam_order_ship_loc_uid = sc.Parameters.Add("@order_ship_loc_uid", SqlDbType.Int);
sqlparam_order_ship_loc_uid.Value = p_auto_allocate_record_uid;
// run query
try
{
SqlDataAdapter sda = new SqlDataAdapter(sc);
sda.Fill(p_return_data); // p_return_data DOES NOT RETAIN DATA AFTER FUNCTION CALL IF OUT KEYWORD IS NOT USED
if (p_return_data != null)
{
if (p_return_data.Rows.Count <= 0)
{
p_return_data = null;
p_message =
$"Could not perform auto-allocation. Please provide IT with the information below.{Environment.NewLine}" +
$"{Environment.NewLine}" +
$"No auto allocation rows returned for UID ({p_auto_allocate_record_uid}).";
is_successful = false;
}
else
{
is_successful = true;
}
}
else
{
p_message =
$"Could not perform auto-allocation. Please provide IT with the information below.{Environment.NewLine}" +
$"{Environment.NewLine}" +
$"Auto allocation query did not instantiate a datatable ({p_auto_allocate_record_uid}).";
is_successful = false;
}
}
catch (Exception ex)
{
p_message =
$"Failed to perform auto-allocation. Please provide IT with the information below.{Environment.NewLine}" +
$"{Environment.NewLine}" +
$"There was an error querying auto allocation result data.{Environment.NewLine}" +
$"Exception Message: ({ex.Message}){Environment.NewLine}" +
$"Inner Exception: ({ex.InnerException}){Environment.NewLine}" +
$"Stack Trace: ({ex.StackTrace})";
is_successful = false;
}
return is_successful;
}
You need to set it to the new DataTable rather than null outside the function. Remember a reference is a pointer to a memory object. But the reference itself is passed by value (on the stack/copied). So you've passed in a reference that doesn't point to a memory object (null) and the copy has been assigned to the DataTable inside the function. When the function finishes the copy is removed from the stack/disgarded and the DataTable goes to the garbage collector.
It's an easy mistake to make if you're not experienced. But now you should have a better understanding for your future coding fun.