Jamie Twells
Jamie Twells

Reputation: 2144

How to store a reference to an object in System.DataTable, rather than a string?

I've written this program:

using System;
using System.Data;

public class Program
{
    public static void Main()
    {
        using (var dt = new DataTable())
        {
            // the data in the table - one row one column
            var person = new
            {
                Name = "ABC",
                Age = 24
            };

            // setup data table
            dt.Columns.Add("Column1");
            var row = dt.NewRow();
            row["Column1"] = person;
            dt.Rows.Add(row);

            // assert
            var storedPerson = dt.Rows[0]["Column1"];

            if(!ReferenceEquals(dt.Rows[0].ItemArray[0], storedPerson))
                throw new Exception();

            if(!ReferenceEquals(storedPerson, person)){
                Console.WriteLine("What is going on?");
                Console.WriteLine($"Person is stored as a [{storedPerson.GetType().Name}]!");
                Console.WriteLine($"Why is it not of type: [{person.GetType().Name}]?");
            }
        }
    }
}

Which you can run here: https://dotnetfiddle.net/LzHPs1

I would expect no exceptions and no output, but I actually get:

What is going on?
Person is stored as a [String]!
Why is it not of type: [<>f__AnonymousType0`2]?

Is the data table class supposed to call ToString() on the objects when they get inserted into the row?

Can I avoid it and store the reference to the object? If I can, how can I do this and if I can't surely Microsoft could have constrained the assignment of the row value to only accept strings and the return type of the index to be string and the ItemArray to be a string array and avoid all this confusion?

Upvotes: 1

Views: 1707

Answers (2)

Hammad Sajid
Hammad Sajid

Reputation: 308

You can avoid it just by defining datatype of column when you are adding a column to you datatable.

i.e

dt.Columns.Add("Column1",typeof(object));

if you didn't specify datatype of column then it will be by default string. Reference Article

Try this code and you will see the magic. :)

using System;
using System.Data


public class Program
{
   public static void Main()
   {
       using (var dt = new DataTable())
       {
           // the data in the table - one row one column
           var person = new
           {
               Name = "ABC",
               Age = 24
           };

           // setup data table
           dt.Columns.Add("Column1",typeof(object));
           var row = dt.NewRow();
           row["Column1"] = person;
           dt.Rows.Add(row);

           // assert
           var storedPerson = dt.Rows[0]["Column1"];

           if(!ReferenceEquals(dt.Rows[0].ItemArray[0], storedPerson))
            throw new Exception();

           if(!ReferenceEquals(storedPerson, person)){
               Console.WriteLine("What is going on?");
               Console.WriteLine($"Person is stored as a [{storedPerson.GetType().Name}]!");
               Console.WriteLine($"Why is it not of type: [{person.GetType().Name}]?");
           }
       }
    }
}

Which you can run here: https://dotnetfiddle.net/y84NCh (Online .Net Compiler)

Upvotes: 1

haim770
haim770

Reputation: 49095

That's because you have added Column1 without denoting its type, hence by default it will be assigned string.

Try to explicitly set it as Object instead:

dt.Columns.Add("Column1", typeof(Object));

See Source

Upvotes: 1

Related Questions