How to write an extension method for DataTable.Row

2019-06-10 09:38发布

问题:

I would like to create an extension method to be implemented like below (if it is even possible) which would be similar to the .ToString() extension method. Can someone please point me in the right direction. I attempted to search it in Google and cannot locate anything.

DataTable table = db.GetInfo(UserId);
if (table.Rows.Count > 0)
{
     bool b = table.Rows[0]["ColumnName"].MyExtensionMethod();
}

I would essentially like to simplify this:

bool b = Convert.IsDBNull(table.Rows[0]["ColumnName"]) ? false : bool.Parse(table.Rows[0]["ColumnName"].ToString());

to

bool b = table.Rows[0]["ColumnName"].DbBoolNullable();

回答1:

Since the indexer of DataRow returns a System.Object, your best bet is something like the following:

public static class Extensions
{
    public static bool DbBoolNullable(this object o)
    {
        return Convert.IsDBNull(o) ? false : bool.Parse(o.ToString());
    }
}

However, I'd strongly advise against this, as since this is an extension method for System.Object (which every class in .NET inherits from), then this method will apply to every variable.

A better way would probably to make an extension method for DataRow:

public static bool GetBool(this DataRow row, string column)
{
   return Convert.IsDbNull(row[column]) ? false : bool.Parse(row[column].ToString());
}

Then you could use it like so:

bool val = table.Rows[0].GetBool("ColumnName");


回答2:

This: table.Rows[0]["ColumnName"] returns an Object.

If you write an extension method for an object, every single class in .Net will get the extension. Try something else.



回答3:

You can do something like,

public static bool DbBoolNullable(this object cell)
{
    return Convert.IsDBNull(cell) ? false : bool.Parse(cell.ToString());
}


回答4:

I think you'd be better off writing the extension method at the DataRow level, or even the DataTable, instead of object. First, you'd avoid polluting object, and it would let you skip some ugly syntax.

So instead of:

table.Rows[0]["ColumnName"].DbBoolNullable()

You could do the extension at the table and end up with:

table.DbBoolNullable(0, "ColumnName")

public static bool DbBoolNullable(this DataTable table, int rowNum, string colName)
{
    return Convert.IsDBNull(table.Rows[rowNum][colName])
        ? false 
        : bool.Parse(table.Rows[rowNum][colName].ToString());
}

Or do it at the row and end up with:

table.Rows[0].DbBoolNullable("ColumnName")

public static bool DbBoolNullable(this DataRow row, string colName)
{
    return Convert.IsDBNull(row[colName])
        ? false 
        : bool.Parse(row[colName].ToString());
}


回答5:

Take a look at my answer here: https://stackoverflow.com/a/5599559/467473 — a while back, I wrote a bunch of extension methods to do just the sort of thing you're wanting to do. To extend this technique, you'll be wanting to look at the documentation on type mapping between C# and SQL Server.

Further, if your using a recentish version of the .Net CLR, take a look at System.Data.DataRowExtensions, which might be just the thing that you're looking for.