2011-08-29 58 views
2

我有一個加載參考數據的數據訪問類。每種類型的實體都將執行它自己的存儲過程並返回一個特定於該實體類型的結果集。然後我有一個方法將數據表的返回值映射到實體。所有的實體類型都具有相同的代碼和名稱的公共屬性我怎樣才能使這個方法通用來處理一種實體?類似這樣的東西是可以推定的,但屬性會導致錯誤。通用方法簽名

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

回答

3

如果你的實體實施該守則的接口和名稱屬性定義,你可能會使用類似:

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屬性。您需要恢復使用反射或動態代碼,或其他一些不太理想的機制來確定這些屬性,而不是在編譯時運行時

+0

謝謝里德和你們所有人誰回答他們是現貨。我知道我很接近,只需要多一點。再次感謝 – Tim

1

如果你所有的實體具有屬性CodeName,我建議讓他們實現與性能CodeName接口ICodedEntity,然後定義你的方法

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

那麼你的代碼有將編譯。

4

你可以有一個定義這些屬性的接口,然後讓你的實體類實現該接口:

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()約束來實際構造新實體;它表明任何通用類型參數都會有一個無參數的構造函數。

2

您需要添加一個type constraintMapDataReaderToEntity<T>,它確保任何T實現Code和Name屬性設置器以及無參數構造函數。