泛型和继承

3

这里有两个问题...

我有一组DataRow包装器(在VS2008中),它们继承自一个基类(称为RecordBase)。它们都有一个名为TableName的字段。我想编写一个通用的枚举器,作为DataSet的扩展方法。特定的TableName将选择要枚举的DataSet中的哪个表。我想写成:

public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase
{
    foreach (DataRow row in MySet.Tables[T.TableName].Rows)
    {
        yield return new T(row);
    }
}

问题1:我找不到一种方法来创建一个可重写的静态字段,这迫使我创建包装器的虚拟实例才能获取TableName。
问题2:尽管包装器(和基类)都有一个接受DataRow的构造函数,但编译器仍然坚持要求我使用无参数的构造函数约束。
所有这些都让我的代码看起来像:
public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase, new()
{
    string TableName = (new T()).TableName;

    foreach (DataRow row in MySet.Tables[TableName].Rows)
    {
        T record = new T();
        record.RowData = row;
        yield return record;
    }
}

有什么想法吗?

1个回答

1

您可以使用自定义属性来指定表名,并使用Activator实例化类型:

[Table("Customers")]
class Customer : RecordBase { }

//...
public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase
{
    var attribT = typeof(TableAttribute);
    var attrib  = (TableAttribute) typeof(T).GetCustomAttributes(attribT,false)[0];

    foreach (DataRow row in MySet.Tables[attrib.TableName].Rows)
    {
        yield return (T) Activator.CreateInstance(typeof(T),new[]{row});
    }
}

1
我忘记了自定义属性。在上面的例子中,我需要用TableName替换TableAttribute,但它似乎可以工作。谢谢。 - Peter Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接