泛型方法签名
本文关键字:泛型方法 | 更新日期: 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;
}
如果没有接口,编译器就无法知道Code
或Name
属性。您将需要恢复使用反射或动态代码,或其他一些不太理想的机制,以便在运行时而不是在编译时确定这些属性。
您需要向MapDataReaderToEntity<T>
添加类型约束,以确保任何T实现Code和Name属性设置器,以及无参数构造函数。
如果你所有的实体都有属性Code
和Name
,我建议让他们实现一个带有属性Code
和Name
的接口ICodedEntity
,然后定义你的方法
private static T MapDataReaderToEntity<T>(IDataReader reader) where T : ICodedEntity, new()
{
var entity = new T();
...
}