How to write an extension method for DataTable.Row

2019-06-10 09:46发布

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();

5条回答
家丑人穷心不美
2楼-- · 2019-06-10 10:19

You can do something like,

public static bool DbBoolNullable(this object cell)
{
    return Convert.IsDBNull(cell) ? false : bool.Parse(cell.ToString());
}
查看更多
祖国的老花朵
3楼-- · 2019-06-10 10:20

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());
}
查看更多
甜甜的少女心
4楼-- · 2019-06-10 10:24

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");
查看更多
Anthone
5楼-- · 2019-06-10 10:31

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.

查看更多
老娘就宠你
6楼-- · 2019-06-10 10:34

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.

查看更多
登录 后发表回答