4

我尝试使用此通用方法扩展 DataRow 对象:

public static T? Get<T>(this DataRow row, string field) where T : struct
{
  if (row.IsNull(field))
    return default(T);
  else
    return (T)row[field];
}

int当 T 为, decimal,double等时它工作正常。

但是当我尝试使用字符串时,我有这个错误:

“类型‘字符串’必须是不可为空的值类型,才能将其用作泛型类型或方法‘System.Nullable’中的参数‘T’”

我该如何纠正这个?

我知道字符串不是结构,但如果字符串字段是 DBNull,我不想返回 null。

4

7 回答 7

6

我认为这就是你想要的:

public static T? GetValue<T>(this DataRow row, string field) where T : struct
{
    if (row.IsNull(field))
        return new T?();
    else
        return (T?)row[field];
}

public static T GetReference<T>(this DataRow row, string field) where T : class
{
    if (row.IsNull(field))
        return default(T);
    else
        return (T)row[field];
}
于 2011-02-09T17:08:28.247 回答
5

string不是一个struct,而是一个class。这就是错误消息告诉您的内容。只需删除约束。

也许您想看看DataRowExtensions

于 2011-02-09T16:53:19.813 回答
2
ds.Tables[7].Rows.OfType<DataRow>().ToList().ForEach(f => tempList.Add(new MyEntity
{
  Id = int.Parse(f.ItemArray[0].ToString()),
  Title = f.ItemArray[1].ToString()
 }));
于 2011-06-24T14:59:16.653 回答
2

不幸的是,您将无法通过使用泛型获得 Nullable 返回类型和对引用类型的支持,除非您在调用时指定希望返回 Nullable

public static T Get<T>(this DataRow row, string field)
{
    if (row.IsNull(field))
        return default(T);
    else
        return (T)row[field];
}

当你打电话时

var id = dr.Get<int?>("user_id");

我没有测试这个,只是把它扔在这里。试一试。

编辑:

或者,如果您真的想将值类型转换为可空值并且仍然能够支持引用类型,那么这样的事情可能会起作用

public static object GetDr<T>(this DataRow row, string field)
{
    // might want to throw some type checking to make 
    // sure row[field] is the same type as T
    if (typeof(T).IsValueType)
    {
        Type nullableType = typeof(Nullable<>).MakeGenericType(typeof(T));
        if (row.IsNull(field))
            return Activator.CreateInstance(nullableType);
        else
            return Activator.CreateInstance(nullableType, new[] { row[field] });
    }
    else
    {
        return row[field];
    }
}

但是,它需要对每次使用进行强制转换

var id = dr.Get<string>("username") as string;
var id = (int?)dr.Get<int>("user_id");

然而,这不会像在泛型类型参数中接受可空类型那样有效。

于 2011-02-09T16:58:06.693 回答
1

您有一个明确的条件阻止它使用字符串:

 where T : struct

System.String是一个类,而不是一个结构。如果您的目标是处理值类型和字符串,我将为字符串创建一个单独的方法,而将其留给您的其他类型。

于 2011-02-09T16:53:27.390 回答
1

正如韦斯指出的那样,您的问题是对结构的约束。我希望扩展方法可以不受限制地工作......

啊,我现在明白了,你正在返回嗯,T?我不确定,但你能定义方法的两种变体吗?structclassT

于 2011-02-09T16:48:52.820 回答
1

这样的事情怎么样?与您的示例不完全相同,但非常适用于引用类型、可空值类型和不可空值类型:

int v = row.Get<int>("vvv");               // throws if column is null
int? w = row.Get<int?>("www");             // set to null if column is null
int x = row.Get<int?>("xxx") ?? -1;        // set to -1 if column is null
string y = row.Get<string>("yyy");         // set to null if column is null
string z = row.Get<string>("zzz") ?? ""    // set to "" if column is null

// ...

public static T Get<T>(this DataRow source, string columnName)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (columnName == null)
        throw new ArgumentNullException("columnName");

    if (columnName.Length < 1)
        throw new ArgumentException("Name cannot be empty.", "columnName");

    if (source.IsNull(columnName))
    {
        T defaultValue = default(T);
        if (defaultValue == null)
            return defaultValue;
    }

    // throws if the column is null and T is a non-nullable value type
    return (T)source[columnName];
}
于 2011-02-09T16:59:28.837 回答