通用方法签名

Posted

技术标签:

【中文标题】通用方法签名【英文标题】:Generic Methods signature 【发布时间】:2011-11-06 05:35:06 【问题描述】:

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

    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);

【问题讨论】:

【参考方案1】:

如果您的所有实体都具有属性CodeName,我建议让它们实现具有属性CodeName 的接口ICodedEntity,然后定义您的方法

private static T MapDataReaderToEntity<T>(IDataReader reader) where T : ICodedEntity, new()

    var entity = new T();
    ...     

然后你的代码将被编译。

【讨论】:

【参考方案2】:

如果您的实体实现了一个定义了 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 属性。您需要恢复使用反射或动态代码,或其他一些不太理想的机制来在运行时而不是在编译时确定这些属性。

【讨论】:

感谢 Reed 和所有回答他们的人。我知道我很接近只是需要一点额外的东西。再次感谢【参考方案3】:

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

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() 约束来实际构造新实体;它表示任何泛型类型参数都将具有无参数构造函数。

【讨论】:

【参考方案4】:

您需要将type constraint 添加到MapDataReaderToEntity&lt;T&gt;,以确保任何 T 实现 Code 和 Name 属性设置器,以及无参数构造函数。

【讨论】:

以上是关于通用方法签名的主要内容,如果未能解决你的问题,请参考以下文章

基于Xposed的通用破解签名的方法

“通用类型系统”(CTS)

使用不同签名的通用回调函数

使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)

在树状通用列表中按字母数字顺序对子项进行排序的扩展方法

如何创建具有可变参数/不同方法签名的方法接口?