2

I have a datatable with 10 columns. I have to check if the cell values in each of the columns contains value A or D, if so I have to replace 'A' with '150' and 'D' with '250' respectively.

I am trying with this ::

foreach (DataRow dr in dt.Rows) 
{
    foreach(var item in dr.ItemArray)
        {
            if( item.ToString()=="A")
            {
                item.ToString().Replace("A", "150");
            }
            if (item.ToString() == "D")
            {
                item.ToString().Replace("A", "250");
            }
        }
}

but the values are not replaced. Why is it so? What is the error with this code ?

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
nischalinn
  • 1,133
  • 2
  • 12
  • 38
  • 1
    It's not just about replacing a string. The question has another important point, which is ignored by the answerers. Assigning a value to an element of the item array or assigning value to a variable pointing to a column value is useless → `var item = row.Columns[i]; item = "something";` is **wrong**). They should replace the whole item array like this `row.ItemArray = anotherArray;` or assign something to the columns value directly: `row.Columns[i] = "something";` – Reza Aghaei Dec 16 '18 at 06:52
  • 1
    Another important point when trying to replace the whole `ItemArray` property → If there is a read-only column, then setting item array will throw an exception. – Reza Aghaei Dec 16 '18 at 07:41
  • 1
    @RezaAghaei Thank You for highlighting these points. Its helpful. – nischalinn Dec 16 '18 at 07:54

1 Answers1

3

Replacing a string is not the whole point in the question. There are some important points, which are ignored by the other answers.

  • Assigning a value to an element of the item array will not change column value.
  • Assigning value to a variable containing the column value will not change the column value.
  • To replace column values using ItemArray, you need to assign a new array the ItemArray property.
  • When trying to replace the ItemArray property, if there is a read-only column, then setting item array will throw an exception.
  • And the point which is already mentioned by other answers, Replace method of the string will return the result replaced string, it will not change the source string.

Just for your information to have a better understanding about ItemArray property, it's the way that the property works, (in short):

Public object[] ItemArray {
    get {
        var values = new object[Columns.Count];
        for (int i = 0; i < values.Length; i++) {
            values[i] = Columns[i];
        }
        return values;
    }
    set {
        for (int i = 0; i < values.Length; i++) {
            //Checks if the column is writable and value is valid
            Columns[i] = value[i];
        }
    }
}

You can read the whole source code as well.

So as a conclusion, the following pieces of code are wrong and will do nothing for you:

  • Wrong: row.ItemArray[i] = "something"; → Will not change column[i]
  • Wrong: var item = row[i]; item = "something"; → Will not change column[i]
  • Wrong var s = "something"; s.Replace("s", "x"); → Will not change s.

Example - Using ItemArray

Please be aware, if there is a read-only column in the data table, the following code will raise an exception:

foreach (DataRow r in dt.Rows)
{
    var a = r.ItemArray;
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        if ($"{a[i]}" == "A") // if($"{a[i]}".Contains("A"))
            a[i] = "150";     //     a[i] = $"{a[i]}".Replace("A", "150");
        if ($"{a[i]}" == "D")
            a[i] = "250";
    }
    r.ItemArray = a;
};

Example - Using Columns Indexer

foreach (DataRow r in dt.Rows)
{
    foreach (DataColumn c in dt.Columns)
    {
        if (c.ReadOnly)
            continue;
        if ($"{r[c]}" == "A") // if($"{r[c]}".Contains("A"))
            r[c] = "150";     //     r[c] = $"{r[c]}".Replace("A", "150");
        else if ($"{r[c]}" == "D")
            r[c] = "250";
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398