【问题标题】:Generics and inheritance泛型和继承
【发布时间】:2011-04-20 23:21:01
【问题描述】:

这里有两个问题...

我有一组继承自基类(称为 RecordBase)的 DataRow 包装器(在 VS2008 中)。它们都有一个名为 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;
    }
}

有什么想法吗?

【问题讨论】:

    标签: c# generics inheritance


    【解决方案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});
        }
    }
    

    【讨论】:

    • 我忘记了自定义属性。在上面的示例中,我需要将 TableAttribute 替换为 TableName,但它似乎可以工作。谢谢。
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    相关资源
    最近更新 更多