0

有人可以帮我弄清楚如何一般地实现这个方法吗?编译器抱怨它无法解析 t.Id。这是有道理的,但是,我如何告诉它所有通过的对象都将具有 Id 属性。这是我为 T 定义的接口:

namespace LiveWire.Model
{
    public interface ILiveWireModel
    {
        Guid Id { get; }
    }
}

所有存储库的接口:

internal interface ILiveWireRepository<T>
{
    ICacheProvider Cache { get; }
    string CacheKey { get; }

    SqlConnection CreateConnection();

    IEnumerable<T> GetData<TD>();

    IEnumerable<T> LoadData<TD>();

    Dictionary<Guid, T> GetCachedData<TD>();

    void ClearCache();
}

还有我的方法:

public IEnumerable<T> GetData<TD>()
        where TD : ILiveWireModel
    {
        var data = GetCachedData<TD>();

        if (data == null)
        {
            data = LoadData<TD>().ToDictionary(t => t.Id);

            if (data.Any())
            {
                Cache.Set(CacheKey, data, 30);
            }
        }

        return data.Values;
    }

我把整个班级都包括在这里,我希望能澄清一些事情。

internal abstract class LiveWireRepositoryBase<T> : ILiveWireRepository<T>
{
    public ICacheProvider Cache { get; private set; }
    public string CacheKey { get; private set; }

    internal LiveWireRepositoryBase()
    {
        Cache = new DefaultCacheProvider();
    }

    public SqlConnection CreateConnection()
    {
        return new SqlConnection(
            ConfigurationManager
            .ConnectionStrings["LiveWire4Database"]
            .ConnectionString);
    }

    public IEnumerable<T> GetData<TD>()
        where TD : ILiveWireModel
    {
        var data = GetCachedData<TD>();

        if (data == null)
        {
            data = LoadData<TD>().ToDictionary(t => t.Id);

            if (data.Any())
            {
                Cache.Set(CacheKey, data, 30);
            }
        }

        return data.Values;
    }

    public IEnumerable<T> LoadData<TD>()
    {
        return new List<T>();
    }

    public Dictionary<Guid, T> GetCachedData<TD>()
    {
        throw new NotImplementedException();
    }


    public void ClearCache()
    {
        throw new NotImplementedException();
    }
}

我收到了这个我不明白的错误。我尝试使用显式接口实现,但这最终使我删除了 where 约束。

方法“LiveWire.Data.Repositories.LiveWireRepositoryBase.GetData()”的类型参数“TD”的约束必须匹配接口方法“LiveWire.Data.Repositories.ILiveWireRepository.GetData()”的类型参数“TD”的约束。考虑改用显式接口实现。C:\projects\LiveWire\Solution\LiveWire.Data\Repositories\LiveWireRepositoryBase.cs 32 31 LiveWire.Data

4

4 回答 4

1

您可以通过将类的签名更改为

public sealed class MyCache<T> where T : ILiveWireModel

(或者,如果该类位于不同的命名空间中,则where T : LiveWire.Model.ILiveWireModel)。

也就是说,我不确定此更改是否会解决您的问题。我只看到了您项目代码的几个片段,所以我可能是错的,并且对以下内容持保留态度:

将 GUID 键控和整数键控值保存在同一个缓存中真的是最好的设计吗?据推测,您从两个不同的来源获取数据,一个使用 GUID 键,另一个使用整数键。但是在未来,如果你添加第三个来源,它也使用整数键呢?来自两个整数键源的键可能会发生冲突,并且对于某些查询,您的缓存总是错误的。就个人而言,我会在某个知道从对象到键的映射的地方维护第二个表或函数(可能保留一个整数值键的映射表,只需通过 GUID 值键),并在我需要时使用该函数检查对象是否被缓存。那么,在其余时间,您的缓存可以直接根据键和值工作,而不必与不同类型的键混淆。

于 2013-02-07T20:36:03.843 回答
0
public IEnumerable<T> GetData<T>() where T:LiveWire.Model.ILiveWireModel { 
  //.../

}

泛型专业化。

于 2013-02-07T20:36:57.183 回答
0

您需要先修复声明

public IEnumerable<T> GetData<T>()

然后,为了知道你可以在 ON T 上使用什么,你必须告诉它 T 被允许是什么。

public IEnumerable<T> GetData<T>() where T : ILiveWireModel

最后,您还没有告诉我们var data实际包含什么,那将在函数GetCachedDataLoadData函数内部,您没有将 T 传递给它,我们也不知道它返回什么。

我希望看到这样的东西

public IEnumerable<T> GetData<T>() where T : ILiveWireModel
{
    var data = GetCachedData<T>();

    if (data == null)
    {
        data = LoadData<T>().ToDictionary(t => t.Id);

        if (data.Any())
        {
            Cache.Set(CacheKey, data, 30);
        }
    }

    return data.Values;
}
于 2013-02-07T20:45:57.303 回答
0

你在这个阶段得到的异常只是说接口定义

IEnumerable<T> GetData<TD>();

where类型参数没有TD与实现相同的约束(即)

public IEnumerable<T> GetData<TD>() where TD : ILiveWireModel

您需要在界面中放置相同的约束。

于 2013-02-07T22:31:56.837 回答