2011-07-18 174 views
2

我不知道如何去这个...非泛型类中的泛型属性?

我有执行各种功能的类:

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是抽象的,不能做新的(),该ISomeInterface预计,是基于关闭EntityBase并执行一类新的()。有什么办法可以做我想做的事吗?


更新:我意识到,对于TKEY的,我可以使用Type,但我还是我不知道要放什么东西了ISomeInterface。

回答

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

而且,即使物业有另外的修饰符(公共的,内部的,受保护的),你可以添加注释,呼叫者的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(); 
} 
0

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

如果你不”我希望MyClass是通用的,你可以使用两种通用的方法来代替:

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

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

你将如何实现的方法是什么? – svick

+0

我想我没有在我的答案中解决后备存储问题。 :) –

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; 
    } 
} 
+0

这只对静态属性有意义。 –

+0

@Ben,你说得对,我已经修复了代码。 – svick