泛型方法签名

本文关键字:泛型方法 | 更新日期: 2023-09-27 18:07:10

我有一个加载引用数据的数据访问类。每种类型的实体都将执行自己的存储过程,并返回特定于该实体类型的结果集。然后我有一个方法将返回值从数据表映射到实体。所有实体类型都有相同的代码和名称的公共属性,我如何使这个方法通用来处理实体类型?像这样的东西是假定的,但是属性会导致错误。

    private static T MapDataReaderToEntity<T>(IDataReader reader)
    {
        var entity = typeof (T);
        entity.Code = SqlPersistence.GetString(reader, "Code");
        entity.Name = SqlPersistence.GetString(reader, "Name");
        return entity;
    }

,我会这样称呼它

_sourceSystem = MapDataReaderToEntity<SourceSystem>(_reader);

泛型方法签名

你可以有一个定义这些属性的接口,然后让你的实体类实现这个接口:

public interface IEntity
{
    string Code { get; set; }
    string Name { get; set; }
}
现在,您可以向您的方法添加一个泛型约束:
public static T MapDataReaderToEntity<T>(IDataReader reader) where T : IEntity, new()
{
    T entity = new T();
    // More code here...
}

请注意,您还需要new()约束来实际构造新实体;它指示任意泛型类型参数将具有无参数构造函数。

如果您的实体实现了定义了Code和Name属性的接口,您可能会使用如下内容:

private static T MapDataReaderToEntity<T>(IDataReader reader)
    where T : IEntity, new()
{
    T entity = new T(); // typeof(T) would return the System.Type, not an instance!
    entity.Code = SqlPersistence.GetString(reader, "Code");
    entity.Name = SqlPersistence.GetString(reader, "Name");
    return entity;
}

如果没有接口,编译器就无法知道CodeName属性。您将需要恢复使用反射或动态代码,或其他一些不太理想的机制,以便在运行时而不是在编译时确定这些属性。

您需要向MapDataReaderToEntity<T>添加类型约束,以确保任何T实现Code和Name属性设置器,以及无参数构造函数。

如果你所有的实体都有属性CodeName,我建议让他们实现一个带有属性CodeName的接口ICodedEntity,然后定义你的方法

private static T MapDataReaderToEntity<T>(IDataReader reader) where T : ICodedEntity, new()
{
    var entity = new T();
    ...     
}