2009-12-15 127 views
3

更新:没有举一个很好的例子。希望现在好一点。C#泛型:更好的方式来匹配泛型的类型?

难道还有比这更好的办法:

(typeof(TRepository) == typeof(UserClass)) 

下面是在写作中的运用:

public static IBaseRepository<TClass> GetRepository<TClass>() where TClass : IDataEntity 
{ 
    IBaseRepository<TClass> repository = null; 

    if (typeof(TClass) == typeof(UserClass)) 
    { 
    repository = (IBaseRepository<TClass>)new UserClassRepository(); 
    } 

    if (typeof(TClass) == typeof(PostClass)) 
    { 
    repository = (IBaseRepository<TClass>)new PostClassRepository(); 
    } 

    return repository; 
} 

如果像这样运行了很多,我希望有更好的办法比的typeof运行一堆。

+0

什么是你想实现什么? 'typeof(TRepository)== typeof(FiftyPostUser)'应该总是* always *为false。 – Graviton 2009-12-15 01:14:24

回答

2

正确的检查是:

if (typeof(TRepository).IsAssignableFrom(typeof(UserClass))) 

此外,如果UserClassRepository其实从IBaseRepository衍生,你并不需要强制转换。

作为事后的想法 - 你为什么这样做?我相信有一种更好的方式可以以更可重复的方式实现你想要的东西。

+0

因为不能将IBaseRepository ''本身分配给'IBaseRepository '类型的变量,所以需要强制转换。 – dtb 2009-12-15 01:25:22

+0

有点扭曲,但试图设计一个易于使用从另一个人的立场点。基本上这样人不必知道存储库类型只是实体类型。 Hopefull IBaseRepository将拥有最基本和最常用的方法,因此不需要投射。 – 2009-12-15 01:36:23

+0

@dtb - T仅限于IDataEntity,这意味着UserClass必须实现IDataEntity – 2009-12-15 01:47:53

6

你在这里做的是一个穷人的inversion of control container。系好安全带,学习dependency injectioninversion of control的概念,然后你可以这样写代码:

IIoCContainer container = new IoCContainer(); 
container.RegisterType<IBaseRepository<UserClass>, UserClassRepository>(); 
container.RegisterType<IBaseRepository<PostClass>, PostClassRepository>(); 
var userClassRepository = container.Resolve<IBaseRepository<UserClass>>(); 

您可以在运行时配置容器(如上),或在配置文件中。您可以指定对象生命周期(瞬态,单例,每个线程或自定义)。依赖注入容器旨在帮助创建对象,特别是对于复杂的对象结构和依赖项,编码到接口而不是具体类型(不再是new ConcreteType())和组件配置。

(顺便说一句,从你的类名(所以UserPost,不UserClassPostClass)下降后缀Class。)

+0

后缀就是这个例子。 其实我工作的地方运行IoC的想法,但我不知道我已经准备好对任何个人的东西复杂的东西。宝贝通过尝试自己弄清楚这一点,踏上了这一步。 – 2009-12-15 03:10:53

+0

看起来像是一个很好的机会坐下来花一天的时间学习这个概念。你会在余生获得奖励。 – jason 2009-12-15 06:28:53

1

你还没有真正确定你的意思是什么“好。”但是,我可能要做的一个方法是为定义存储库的每个TClass创建一个自定义属性,并在您的GetRepository方法中读取该属性。它使用了一些Reflection,但它比一个大的if-else更优雅,并且比完整的依赖注入框架更轻量。简单的例子:

属性:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 
public class RepositoryAttribute : Attribute 
{ 
    public RepositoryAttribute(Type repositoryType) 
    { 
     this.RepositoryType = repositoryType; 
    } 

    public Type RepositoryType { get; private set; } 
} 

实体类:

[Repository(typeof(UserClassRepository))] 
public class UserClass 
{ 
    // Class code 
    // ... 
} 

工厂方法:

public static IBaseRepository<TClass> GetRepository<TClass>() 
    where TClass : IDataEntity 
{ 
    Type t = typeof(TClass); 
    RepositoryAttribute attr = 
     (RepositoryAttribute)Attribute.GetCustomAttribute(t, 
      typeof(RepositoryAttribute), false); 
    if (attr != null) 
    { 
     return (IBaseRepository<TClass>)Activator.CreateInstance(attr.RepositoryType); 
    } 
    return null; 
}