【问题标题】:Is this a covariance/contravariance issue with my design?这是我的设计的协方差/逆变问题吗?
【发布时间】:2014-09-01 13:18:07
【问题描述】:

我正在努力解决我认为我的设计存在协变/逆变问题。我想返回一个只在运行时才知道的通用对象。

我有以下类/接口

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,它允许我获取/设置检索/更新数据。

但是,我不知道如何调用 Retrieve/Update,因为我无法转换为 IDomainRepository,因为我不知道我将使用什么域对象。

我一直在阅读协变/逆变,因为我认为它与此有关 然而,我也觉得我的设计是错误的,因为我把它弄得太复杂了。 我相信我可以在说 c# 2.0 中实现这一点,所以我认为我不应该担心协变/逆变。

这是我的设计还是我需要整理我的输入/输出接口?

【问题讨论】:

  • 我没有看到任何 contra 或 covariance 的用法;那你为什么要问你的代码呢?
  • 直接返回IDomainRepository&lt;T&gt;

标签: c# .net oop variance


【解决方案1】:

按照评论者的建议,将工厂更改为返回 IDomainRepository&lt;T&gt;。否则使用as 运算符对接口指针进行类型转换:

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

但测试对象以识别其类型并不鼓励多态行为。

另见Test if object implements interface

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多