非泛型类中的泛型属性?

时间:2011-07-18 20:25:12

标签: c# generics collections dictionary constraints

我不知道该怎么做......

我有一个执行各种功能的课程:

public abstract class EntityBase { ... }

public interface ISomeInterface<T> where T : EntityBase, new() { ... }

public class SomeClass<T> : ISomeInterface<T> { ... }

我正在尝试在非泛型类中拥有这些缓存:

public class MyClass
{
    //Not sure how to do this
    private ConcurrentDictionary<?, ISomeInterface<?>> Cache { get; set; }
}

问题是EntityBase是抽象的,不能做new(),ISomeInterface需要一个基于EntityBase并执行new()的类。有没有办法做我想做的事情?


更新:我意识到对于TKey我可以使用Type,但我仍然不确定要为ISomeInterface放置什么。

3 个答案:

答案 0 :(得分:2)

首先,我认为您打算使用ConcurrentDictionary,因为您有一个键/值对。

其次,你可以这样做,类似于ICloneable。 ICloneable有一个返回Object而不是T的方法。

private ConcurrentDictionary<Type, Object> Cache { get; set; }

由于它是私有的,您可以在内部进行管理并根据需要进行投射。显然,你必须确保任何函数调用都有一个typeparam定义,例如:

//I omitted error checking on all the examples.
public class Foo : EntityBase { ... }

void DoSomething<Foo>()
{
    var someClass = Cache[typeof(Foo)] as ISomeInterface<Foo>
    someClass.Bar();
}

此外,即使属性具有另一个修饰符(public,internal,protected),您也可以向调用者添加注释,即Object是ISomeInterface的泛型类型,其中T是EntityBase,new()。然后,他们只需要施放他们需要的东西。


您还可以在非泛型类上使用泛型方法将缓存项作为泛型类型:

ISomeInterface<T> GetInstance<T>()
    where T : EntityBase, new()
{
    return Cache[typeof(T)] as ISomeInterface<T>;
}

void AddInstance<T>(ISomeInterface<T> instance)
    where T : EntityBase, new()
{
    Cache[typeof(T)] = instance;
}

void DoSomething<T>()
{
    var someClass = GetInstance<T>();
    someClass.Bar();
}

答案 1 :(得分:0)

请参阅此相关问题:Making a generic property

如果您不希望MyClass是通用的,则可以使用两种通用方法:

    private ConcurrentCollection<T, ISomeInterface<T>> GetCache<T>()
    {
        ...
    }

    private void SetCache<T>(ConcurrentCollection<T, ISomeInterface<T>> cache)
    {
        ...
    }

答案 2 :(得分:0)

我不确定你究竟想要使用那个集合,但是做一些类似的事情的方法是创建一个包含值的嵌套通用静态类:

class SomeInterfaceCollection
{
    private static class Item<T>
    {
        public static ISomeInterface<T> Value;
    }

    public static ISomeInterface<T> Get<T>()
    {
        return Item<T>.Value;
    }

    public static void Set<T>(ISomeInterface<T> value)
    {
        Item<T>.Value = value;
    }
}