2014-07-11 60 views
2

我正在努力與我認爲是我的設計中的協變/逆變問題。我想返回一個只在運行時才知道的通用對象。這是我的設計中的協變/逆變問題嗎?

我有以下類/接口

public interface IBaseRepository 
{ 
    int UserId { get; set; } 

    // Retrieve 
    SyncData GetRetrieveData(); 

    // Update 
    SyncData GetUpdateData(); 
} 

public interface IDomainRepository<T> : IBaseRepository where T : IDomainObject 
{ 
    object GetValue(T domainObject, string id); 
    void SetValue(T domainObject, string id, object value); 

    // retrieve data 
    BatchResults<T> Retrieve(); 

    // update data 
    BatchResults<T> Update(SynchroniseList synchroniseList); 
} 

我有這些的實現:

public abstract class BaseRepository : IBaseRepository 
{ 
    public int UserId { get; set; } 

    public virtual SyncData GetRetrieveData() 
    { 
     return new SyncData(); 
    } 

    public virtual SyncData GetUpdateData() 
    { 
     return new SyncData(); 
    } 
} 

public MyTaskRepository : BaseRepository, IDomainRepository<MyTask> 
{ 
    public object GetValue(MyTask domainObject, string id) 
    { 
     return domainObject.GetValue(); 
    } 

    void SetValue(MyTask domainObject, string id, object value) 
    { 
     domainObject.SetValue(); 
    } 

    // retrieve data 
    public BatchResults<MyTask> Retrieve() 
    { 
     // do stuff specific to MyTask 
     return new BatchResults<MyTask>(); 
    } 

    // update data 
    BatchResults<T> Update(SynchroniseList synchroniseList) 
    { 
     // do stuff specific to MyTask 
     return new BatchResults<MyTask>(); 
    } 
} 

public MyOtherTaskRepository : BaseRepository, IDomainRepository<MyOtherTask> 
{ 
    ... 
} 

使用這個倉庫時,我遇到的問題是。在我有一個表格

IBaseRepository repo = RepositoryFactory.Create(some parameters); 

這將返回一個IDomainRepository,它允許我獲取/設置檢索/更新數據。

但是,我不知道如何調用檢索/更新,因爲我不能轉換爲IDomainRepository,因爲我不知道我將使用哪個域對象。

我一直在閱讀協變/逆變,因爲我認爲它與 有關 但是,我也有這樣的感覺,即我的設計是錯誤的,因爲我使這個過於複雜。 我相信我可以在c#2.0中實現這一點,所以我認爲我不應該關注協變/逆變。

它是我的設計還是我需要整理我的輸入/輸出接口?

+0

我沒有看到反對或協方差的任何用法;那麼你爲什麼要問你的代碼呢? –

+0

只是返回'IDomainRepository '而不是。 – tia

回答

0

按照評論者的建議,將工廠更改爲返回IDomainRepository<T>。否則,使用as運算符類型轉換接口指針:

IBaseRepository repo = RepositoryFactory.Create(...); 
IDomainRepository<MyTask> domainRepo = repo as IDomainRepository<MyTask>; 
if (domainRepo != nil) 
{ 
    // domainRepo implements IDomainRepository<MyTask>. 
} 

但測試的對象,以確定其類型不鼓勵多態行爲。請參閱Test if object implements interface