Checking if something is empty - c#

I am currently checking if comboboxes and numericupdowns are empty but i am doing it with If statement.
Can you tell me if there is any other faster way of doing it?
Here is current code
private void button1_Click(object sender, EventArgs e)
{
if(comboBox1.SelectedItem != null)
{
if(comboBox2.SelectedItem != null)
{
if(numericUpDown1.Value != 0)
{
if(numericUpDown2.Value != 0)
{
if(numericUpDown3.Value != 0)
{
if(numericUpDown4.Value != 0)
{
string domacin = "" + comboBox1.GetItemText(comboBox1.SelectedItem);
int D_kosevaPrvoPoluvreme = (int)numericUpDown1.Value;
int D_kosevaDrugoPoluvreme = (int)numericUpDown3.Value;
int D_ukupnoKoseva = D_kosevaDrugoPoluvreme + D_kosevaPrvoPoluvreme;
int D_primljenihKosevaPrvoPoluvreme = (int)numericUpDown2.Value;
int D_primljenihKosevaDrugoPoluvreme = (int)numericUpDown4.Value;
int D_ukupnoPrimljenihKoseva = D_primljenihKosevaDrugoPoluvreme + D_primljenihKosevaPrvoPoluvreme;
string gost = "" + comboBox2.GetItemText(comboBox2.SelectedItem);
int G_kosevaPrvoPoluvreme = (int)numericUpDown2.Value;
int G_kosevaDrugoPoluvreme = (int)numericUpDown4.Value;
int G_ukupnoKoseva = G_kosevaDrugoPoluvreme + G_kosevaPrvoPoluvreme;
int G_primljenihKosevaPrvoPoluvreme = (int)numericUpDown1.Value;
int G_primljenihKosevaDrugoPoluvreme = (int)numericUpDown3.Value;
int G_ukupnoPrimljenihKoseva = G_primljenihKosevaDrugoPoluvreme + G_primljenihKosevaPrvoPoluvreme;
int rezultat;
Functions.odrediPobednika(out rezultat, D_ukupnoKoseva, G_ukupnoKoseva);
//SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\arist\Documents\VisualStudio2015\Projects\NBA\NBA\NBA.mdf;Integrated Security=True");
//SqlCommand cmd = new SqlCommand("", con);
}
}
}
}
}
}
}

I would use following fail-fast-validation approach with meaningful messages:
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedItem == null)
{
MessageBox.Show("Meaningful message, user should know what he has done wrong", "Invalid xyz");
return;
}
else if (comboBox2.SelectedItem == null)
{
MessageBox.Show("Meaningful message, user should know what he has done wrong", "Invalid xyz");
return;
}
else if (numericUpDown1.Value == 0)
{
MessageBox.Show("Meaningful message, user should know what he has done wrong", "Invalid xyz");
return;
}
else if (numericUpDown2.Value == 0)
{
MessageBox.Show("Meaningful message, user should know what he has done wrong", "Invalid xyz");
return;
}
else if (numericUpDown3.Value == 0)
{
MessageBox.Show("Meaningful message, user should know what he has done wrong", "Invalid xyz");
return;
}
// insert code
}
It's neither shorter nor more efficient, but it's easy to read, to debug and most important: the user knows what went wrong. You should also use meaningful control-names.
Of course you could also use one if and concat all conditions with &&, but i'd prefer my first approach for the reasons mentioned above.
bool valid = comboBox1.SelectedItem != null
&& comboBox2.SelectedItem != null
&& numericUpDown1.Value != 0
&& numericUpDown2.Value != 0
&& numericUpDown3.Value != 0
&& numericUpDown4.Value != 0;
if(valid){
//Code
}

The first thing that springs to mind is to use one if statement
if(comboBox1.SelectedItem != null && comboBox2.SelectedItem != null && numericUpDown1.Value != 0 && numericUpDown2.Value != 0 && numericUpDown3.Value != 0 && numericUpDown4.Value != 0)
{
//Code
}
This can also be put onto multiple lines for readability
if(comboBox1.SelectedItem != null &&
comboBox2.SelectedItem != null &&
numericUpDown1.Value != 0 &&
numericUpDown2.Value != 0 &&
numericUpDown3.Value != 0 &&
numericUpDown4.Value != 0)
{
//Code
}

There's not much to optimize there in reference to execution times etc. But the code could be made a bit neater, a start could be something like:
private void button1_Click(object sender, EventArgs e)
{
if(comboBox1.SelectedItem != null &&
comboBox2.SelectedItem != null &&
numericUpDown1.Value != 0 &&
numericUpDown2.Value != 0 &&
numericUpDown3.Value != 0 &&
numericUpDown4.Value != 0)
{
string domacin = comboBox1.GetItemText(comboBox1.SelectedItem);
int D_kosevaPrvoPoluvreme = (int)numericUpDown1.Value;
int D_kosevaDrugoPoluvreme = (int)numericUpDown3.Value;
int D_ukupnoKoseva = D_kosevaDrugoPoluvreme + D_kosevaPrvoPoluvreme;
int D_primljenihKosevaPrvoPoluvreme = (int)numericUpDown2.Value;
int D_primljenihKosevaDrugoPoluvreme = (int)numericUpDown4.Value;
int D_ukupnoPrimljenihKoseva = D_primljenihKosevaDrugoPoluvreme + D_primljenihKosevaPrvoPoluvreme;
string gost = comboBox2.GetItemText(comboBox2.SelectedItem);
int G_kosevaPrvoPoluvreme = (int)numericUpDown2.Value;
int G_kosevaDrugoPoluvreme = (int)numericUpDown4.Value;
int G_ukupnoKoseva = G_kosevaDrugoPoluvreme + G_kosevaPrvoPoluvreme;
int G_primljenihKosevaPrvoPoluvreme = (int)numericUpDown1.Value;
int G_primljenihKosevaDrugoPoluvreme = (int)numericUpDown3.Value;
int G_ukupnoPrimljenihKoseva = G_primljenihKosevaDrugoPoluvreme + G_primljenihKosevaPrvoPoluvreme;
int rezultat;
Functions.odrediPobednika(out rezultat, D_ukupnoKoseva, G_ukupnoKoseva);
//SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\arist\Documents\VisualStudio2015\Projects\NBA\NBA\NBA.mdf;Integrated Security=True");
//SqlCommand cmd = new SqlCommand("", con);
}
}

Related

How to fix an operator to a void call in a button?

I'm a beginner C# dev and I am forgetting something. The (!ValidateCleared(actionsChecked))code is throwing and error the Operator ! cannot be applied to a void. Not sure how to fix this in this example. I tried keeping it a bool and using a break, but the actions didn't behave as expected. It only checked the one action.
protected void btnSubmit_Click(object sender, EventArgs e)
{
ValidateActionSelected();enter code here
ValidateCleared(actionsChecked);
if (!ValidateCleared(actionsChecked))
{
if (String.Equals(ddlActionsAndDocuments.SelectedItem.Text.ToString(), "XXX YYY") || String.Equals(ddlActionsAndDocuments.SelectedItem.Text.ToString(), "XXX ZZZ"))
{
reqEffectiveDate.ErrorMessage = "";
}
if (ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXYYY ||
ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXYYYDenial ||
ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXzzz)
{
ValidateXXXYYY(actionsChecked, ddlActionsAndDocuments.Text);
}
if (ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.WWW ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYZZZ ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYWWW ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYWaived)
{
ValidateCertificate(actionsChecked, ddlActionsAndDocuments.Text);
}
}
}
private void ValidateCleared(List<xxCaseEntity> actionsChecked)
{
//bool error = false;
foreach (xxCaseEntity ACTIONyy in actionsChecked)
{
if (ACTIONyy.XXStatusCode == 40 || ACTIONyy.XXStatusCode == 45)
{
//error = true;
DisplayErrorMessage("FR Action Cannot Apply to " + ACTIONyy.CaseIdentifier);
actionsChecked.Remove(ACTIONyy);
//break;
}
}
return;
//return error;
}
The fixed code is below
protected void btnSubmit_Click(object sender, EventArgs e)
{
ValidateActionSelected();enter code here
ValidateCleared(actionsChecked);
if (!ValidateCleared(actionsChecked))
{
if (String.Equals(ddlActionsAndDocuments.SelectedItem.Text.ToString(), "XXX YYY") || String.Equals(ddlActionsAndDocuments.SelectedItem.Text.ToString(), "XXX ZZZ"))
{
reqEffectiveDate.ErrorMessage = "";
}
if (ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXYYY ||
ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXYYYDenial ||
ddlActionsAndDocuments.SelectedValue == ActionTypes.XXXzzz)
{
ValidateXXXYYY(actionsChecked, ddlActionsAndDocuments.Text);
}
if (ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.WWW ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYZZZ ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYWWW ||
ddlActionsAndDocuments.SelectedValue == InsuranceActionTypes.YYYWaived)
{
ValidateCertificate(actionsChecked, ddlActionsAndDocuments.Text);
}
}
}
private bool ValidateCleared(List<xxCaseEntity> actionsChecked)
{
List<xxCaseEntity> removeItems = new List<xxCaseEntity>();
foreach (xxCaseEntity ACTIONyy in actionsChecked)
{
if (ACTIONyy.XXStatusCode == 40 || ACTIONyy.XXStatusCode == 45)
{
DisplayErrorMessage("FR Action Cannot Apply to " + ACTIONyy.CaseIdentifier);
//actionsChecked.Remove(ACTIONyy);
removeItems.Add(ACTIONyy);
}
}
foreach(xxCaseEntity ACTIONyy in removeItems)
{
actionsChecked.Remove(ACTIONyy);
}
return true;
}

When I redo using this undo/redo code, the first thing undone cannot be redone

I am using the following code in order to implement undo/redo into my application:
public struct UndoSection
{
public string Undo;
public int Index;
}
--
public UndoSection(int index, string undo)
{
Index = index;
Undo = undo;
}
--
Stack<UndoSection> UndoStack = new Stack<UndoSection>();
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.None && e.KeyCode == Keys.Delete)
UndoStack.Push(new UndoSection(richTextBoxPrintCtrl1.SelectionStart, richTextBoxPrintCtrl1.SelectedText));
else if (e.Control && e.KeyCode == Keys.Z)
{
e.Handled = true;
undo_Click(richTextBoxPrintCtrl1, new EventArgs());
}
}
public string[] RTBRedoUndo;
public int StackCount = 0;
public int OldLength = 0;
public int ChangeToSave = 5;
public bool IsRedoUndo = false;
--
public void RTBTextChanged()
{
if (richTextBoxPrintCtrl1.TextLength - OldLength >= ChangeToSave | richTextBoxPrintCtrl1.TextLength - OldLength <= ChangeToSave)
{
StackCount += 1;
RTBRedoUndo[StackCount] = richTextBoxPrintCtrl1.Text;
}
}
public void UndoCode()
{
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount - 1] != null)
{
StackCount = StackCount - 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
}
public void RedoCode()
{
if (IsRedoUndo == false && richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " ")
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
{
StackCount = StackCount + 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
However, if I type some text in my rich text box such as: "Hello. This is my application.", It will only let me redo up to "my". It won't let me redo "application.". And if I undo all text, I then cannot redo and restore the text.
What is causing this to behave in this manner? I really need to get this undo/redo code working correct. Could somebody help point me in the right direction, please?
--EDIT--
Redo code:
public void RedoCode()
{
if (IsRedoUndo == false && richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " ")
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
{
StackCount = StackCount + 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
}
It is called by a button click, using RedoCode();
Can you show how to call the Redo function?
as from what I can see you've missed out the below code
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.None && e.KeyCode == Keys.Delete)
UndoStack.Push(new UndoSection(richTextBoxPrintCtrl1.SelectionStart, richTextBoxPrintCtrl1.SelectedText));
else if (e.Control && e.KeyCode == Keys.Z)
{
e.Handled = true;
undo_Click(richTextBoxPrintCtrl1, new EventArgs());
}
else if (e.Control && e.KeyCode == Keys.Y)
{
e.Handled = true;
redo_Click(richTextBoxPrintCtrl1, new EventArgs());
}

Validating the integer

I want a Decimal Point in an Integer. If decimal Point is not there it shows Error Message.
Sir, The following code is written in User Control Text Box.The maximum Length given by the user When he access the user control.
The following code is restricts the user to enter the Decimal point after the maximum length.
Please the run the code Sir,
public virtual int MaximumLength { get; set; }
private void txtCurrency_KeyPress(object sender, KeyPressEventArgs e)
{
txtCurrency.MaxLength = MaximumLength + 3;
int dotIndex = txtCurrency.Text.IndexOf('.');
if (e.KeyChar != (char)Keys.Back)
{
if (char.IsDigit(e.KeyChar))
{
if (dotIndex != -1 && dotIndex < txtCurrency.SelectionStart && txtCurrency.Text.Substring(dotIndex + 1).Length >= 2)
{
e.Handled = true;
}
else if (txtCurrency.Text.Length == MaximumLength)
{
if (e.KeyChar != '.')
{ e.Handled = true; }
}
}
else
{
e.Handled = e.KeyChar != '.' || dotIndex != -1 || txtCurrency.Text.Length == 0 || txtCurrency.SelectionStart + 2 < txtCurrency.Text.Length;
}
}`enter code here`
decimal myValue = 12.4m;
int value = 0;
if (myValue - Math.Round(myValue) != 0)
{
throw new Exception("Has a decimal point");
}
else
{
value = (int)myValue;
}
You can use the RegularExpressions
private void textBox2_Validating(object sender, CancelEventArgs e)
{
Regex r = new Regex(#"^\d+.\d{0,1}$");
if (r.IsMatch(textBox2.Text))
{
MessageBox.Show("Okay");
}
else
{
e.Cancel = true;
MessageBox.Show("Error");
}
}
UPDATE:
private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.')
e.Handled = true;
if (e.KeyChar == '.'
&& (textBox2).Text.IndexOf('.') > -1) //Allow one decimal point
e.Handled = true;
}

Iterate through specific col in DGVs' & compare the string values

I got 2 datagrid views, First datagrid 1st col or Index 0 & the Second datagrid 1st col or Index 0.
How can i loop through a specific col in the datagridviews and look for the string values,if it matches with the list then go to a function.
My approach is not working. How can i do this?
private void b_calculate_Click(object sender, EventArgs e)
{
List<string> value = new List<String>() { "AE0", "AT1", "AT2", "AT3"};
value = new List<string>(datagridview1.Columns[0].Index);
List<string> value2 = new List<String>() { "BE0", "BT1", "BT2", "BT3"};
value2 = new List<string>(datagridview2.Columns[0].Index);
//First Combination
if((value.ToString() == "AT1" || value.ToString() == "AE0" ||
value.ToString() == "AT2")
&&
(value2.ToString() == "BT1" || value2.ToString() == "BE0"))
{
gottoFunction1();
}
//Second Combination
if((value.ToString() == "AT1" || value.ToString() == "AT2" )
&&
(value2.ToString() == "BT1" || value2.ToString() == "BT2"))
{
gottoFunction2();
}
}
Here's a routine that iterates through all available rows in both DataGridViews and does the processing shown in your method:
private void b_calculate_Click(object sender, EventArgs e)
{
for (var i = 0; i < dataGridView1.RowCount; i++)
{
if (dataGridView2.RowCount <= i)
break;
var cellFromDG1 = dataGridView1.Rows[i].Cells[0];
var cellFromDG2 = dataGridView1.Rows[i].Cells[0];
if (cellFromDG1.Value == null || cellFromDG2.Value == null)
{
// this could be the empty row that allows you to
// enter a new record
continue;
}
var value = cellFromDG1.Value.ToString();
var value2 = cellFromDG2.Value.ToString();
if ((value == "AT1" || value == "AE0" || value == "AT2") &&
(value2 == "BT1" || value2 == "BE0"))
{
gottoFunction1();
}
if ((value == "AT1" || value == "AT2") &&
(value2 == "BT1" || value2 == "BT2"))
{
gottoFunction2();
}
}
}

Workflow for Collection.Add()

DataTable.Rows.Add() adds a row to the data table. However, how does it handle the underlying array?
When adding a single row at a time, does it rebuild the entire array with each row added?
Or is it able to simply modify the existing array without any hit on performance?
I am wondering if it’s better to determine the size of the array before filling it with data, or if somehow the data table is able to modify the collection without (behind the scenes) copying and moving things.
It’s my understanding that to adjust an array you have to redefine it and move previously existing data into the new structure.
My question is what is the work flow for the Collection.Add() method?
Take a look using software like DotPeek:
DataTable.Rows.Add(DataRow row)
{
this.table.AddRow(row, -1);
}
which calls:
DataTable.AddRow(DataRow row, int proposedID)
{
this.InsertRow(row, proposedID, -1);
}
which calls:
DataTable.InsertRow(DataRow row, int proposedID, int pos)
{
this.InsertRow(row, (long) proposedID, pos, true);
}
which calls:
DataTable.InsertRow(DataRow row, long proposedID, int pos, bool fireEvent)
{
Exception deferredException = (Exception) null;
if (row == null)
throw ExceptionBuilder.ArgumentNull("row");
if (row.Table != this)
throw ExceptionBuilder.RowAlreadyInOtherCollection();
if (row.rowID != -1L)
throw ExceptionBuilder.RowAlreadyInTheCollection();
row.BeginEdit();
int proposedRecord = row.tempRecord;
row.tempRecord = -1;
if (proposedID == -1L)
proposedID = this.nextRowID;
bool flag;
if (flag = this.nextRowID <= proposedID)
this.nextRowID = checked (proposedID + 1L);
try
{
try
{
row.rowID = proposedID;
this.SetNewRecordWorker(row, proposedRecord, DataRowAction.Add, false, false, pos, fireEvent, out deferredException);
}
catch
{
if (flag && this.nextRowID == proposedID + 1L)
this.nextRowID = proposedID;
row.rowID = -1L;
row.tempRecord = proposedRecord;
throw;
}
if (deferredException != null)
throw deferredException;
if (!this.EnforceConstraints || this.inLoad)
return;
int count = this.columnCollection.Count;
for (int index = 0; index < count; ++index)
{
DataColumn dataColumn = this.columnCollection[index];
if (dataColumn.Computed)
dataColumn.CheckColumnConstraint(row, DataRowAction.Add);
}
}
finally
{
row.ResetLastChangedColumn();
}
}
which calls:
DataTable.SetNewRecordWorker(DataRow row, int proposedRecord, DataRowAction action, bool isInMerge, bool suppressEnsurePropertyChanged, int position, bool fireEvent, out Exception deferredException)
{
deferredException = (Exception) null;
if (row.tempRecord != proposedRecord)
{
if (!this.inDataLoad)
{
row.CheckInTable();
this.CheckNotModifying(row);
}
if (proposedRecord == row.newRecord)
{
if (!isInMerge)
return;
this.RaiseRowChanged((DataRowChangeEventArgs) null, row, action);
return;
}
else
row.tempRecord = proposedRecord;
}
DataRowChangeEventArgs args = (DataRowChangeEventArgs) null;
try
{
row._action = action;
args = this.RaiseRowChanging((DataRowChangeEventArgs) null, row, action, fireEvent);
}
catch
{
row.tempRecord = -1;
throw;
}
finally
{
row._action = DataRowAction.Nothing;
}
row.tempRecord = -1;
int record = row.newRecord;
int num = proposedRecord != -1 ? proposedRecord : (row.RowState != DataRowState.Unchanged ? row.oldRecord : -1);
if (action == DataRowAction.Add)
{
if (position == -1)
this.Rows.ArrayAdd(row);
else
this.Rows.ArrayInsert(row, position);
}
List<DataRow> cachedRows = (List<DataRow>) null;
if ((action == DataRowAction.Delete || action == DataRowAction.Change) && (this.dependentColumns != null && this.dependentColumns.Count > 0))
{
cachedRows = new List<DataRow>();
for (int index = 0; index < this.ParentRelations.Count; ++index)
{
DataRelation relation = this.ParentRelations[index];
if (relation.ChildTable == row.Table)
cachedRows.InsertRange(cachedRows.Count, (IEnumerable<DataRow>) row.GetParentRows(relation));
}
for (int index = 0; index < this.ChildRelations.Count; ++index)
{
DataRelation relation = this.ChildRelations[index];
if (relation.ParentTable == row.Table)
cachedRows.InsertRange(cachedRows.Count, (IEnumerable<DataRow>) row.GetChildRows(relation));
}
}
if (!suppressEnsurePropertyChanged && !row.HasPropertyChanged && (row.newRecord != proposedRecord && -1 != proposedRecord) && -1 != row.newRecord)
{
row.LastChangedColumn = (DataColumn) null;
row.LastChangedColumn = (DataColumn) null;
}
if (this.LiveIndexes.Count != 0)
{
if (-1 == record && -1 != proposedRecord && (-1 != row.oldRecord && proposedRecord != row.oldRecord))
record = row.oldRecord;
DataViewRowState recordState1 = row.GetRecordState(record);
DataViewRowState recordState2 = row.GetRecordState(num);
row.newRecord = proposedRecord;
if (proposedRecord != -1)
this.recordManager[proposedRecord] = row;
DataViewRowState recordState3 = row.GetRecordState(record);
DataViewRowState recordState4 = row.GetRecordState(num);
this.RecordStateChanged(record, recordState1, recordState3, num, recordState2, recordState4);
}
else
{
row.newRecord = proposedRecord;
if (proposedRecord != -1)
this.recordManager[proposedRecord] = row;
}
row.ResetLastChangedColumn();
if (-1 != record && record != row.oldRecord && (record != row.tempRecord && record != row.newRecord) && row == this.recordManager[record])
this.FreeRecord(ref record);
if (row.RowState == DataRowState.Detached && row.rowID != -1L)
this.RemoveRow(row, false);
if (this.dependentColumns != null)
{
if (this.dependentColumns.Count > 0)
{
try
{
this.EvaluateExpressions(row, action, cachedRows);
}
catch (Exception ex)
{
if (action != DataRowAction.Add)
throw ex;
deferredException = ex;
}
}
}
try
{
if (!fireEvent)
return;
this.RaiseRowChanged(args, row, action);
}
catch (Exception ex)
{
if (!ADP.IsCatchableExceptionType(ex))
throw;
else
ExceptionBuilder.TraceExceptionWithoutRethrow(ex);
}
}
which calls one of those:
DataRowCollection.ArrayAdd(DataRow row)
{
row.RBTreeNodeId = this.list.Add(row);
}
DataRowCollection.ArrayInsert(DataRow row, int pos)
{
row.RBTreeNodeId = this.list.Insert(pos, row);
}
this.list is of type DataRowCollection.DataRowTree, derived from RBTree<DataRow>.
private sealed class DataRowTree : RBTree<DataRow>
RBTree<DataRow> and RBTreeNodeId allows us to conclude that a Red-Black tree is being used!

Categories

Resources