0

I wrote a class CustomDataTable that inherits DataTable but adds the function ToHtml()

CustomDataTable

public static CustomDataTable : DataTable {
   public Table ToHtml() {
       Table tbl;
       /*
            logic for converting each row in the DataTable to HTML TableRow
       */
       return tbl;
   }
}

Usage:

public static CustomDataTable getTable(String sql) {
    SqlConnection con = new SqlConnection(connection_string);
    SqlCommand cmd = new SqlCommand(sql,con);
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    DataSet ds = new DataSet();
    da.Fill(ds);
    return (CustomDataTable)ds.Tables[0];   // this line triggers the exception
        // Unable to cast object of type 'System.Data.DataTable' to type 'MyProject.CustomDataTable'

}

Why did the cast fail?

Ahmad
  • 12,336
  • 6
  • 48
  • 88
  • You can't cast to a more derived type. – ProgrammingLlama Apr 04 '19 at 11:29
  • You have to create a Copy method where you read the DataTable and insert data cell by cell into the CustomDataTable, there's no automatic relation between them otherwise to do the typecasting – Mrinal Kamboj Apr 04 '19 at 11:32
  • @MrinalKamboj is there a way to extend the class `DataTable` so that it can perform the new method? – Ahmad Apr 04 '19 at 11:33
  • @Ahmad extension method. See [this answer](https://stackoverflow.com/a/40802711/3181933). The `static` class and `static` method are important. – ProgrammingLlama Apr 04 '19 at 11:34
  • @Ahmad extending shall not be an issue, but filling would pose the same challenge since DataAdapter doesn't know about the `CustomDataTable` – Mrinal Kamboj Apr 04 '19 at 11:35
  • Easier way would be instead of extending aggregate the DataTable and then use it in the Custom method – Mrinal Kamboj Apr 04 '19 at 11:36
  • Write it as an extension method instead if you want to add functionality to a base class, otherwise you need to create the original object as an instance of your new type. – Steve Todd Apr 04 '19 at 11:37
  • 1
    Can you instead try the following `public int Fill(DataTable dataTable)` method of the `SqlDataAdapter`, whic shall be able to take the instance of the `CustomDataTable` and thus fill the data into it – Mrinal Kamboj Apr 04 '19 at 11:40

1 Answers1

2

Why did the cast fail?

Because it's invalid. ds.Tables[0] returns a DataTable and nothing else and you can't cast a DataTable to a more derived type like CustomDataTable.

Instead of creating a derived class, you could consider creating an extension method that extends DataTable with a ToHtml() method:

public static class MyExtensions
{
    public Table ToHtml(this DataTable dt)
    {
        /*
             logic for converting each row in the DataTable to HTML TableRow
        */
    }
}

You could then call this one on any DataTable without casting, e.g.:

var htmlTable = ds.Tables[0].ToHtml();
mm8
  • 163,881
  • 10
  • 57
  • 88