C#泛型:匹配泛型类型到另一个类型的更好方法?

3

更新:之前的例子不太好,请看下面的例子。

有没有比下面这种方法更好的呢:

(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。

你想要实现什么?typeof(TRepository) == typeof(FiftyPostUser) 应该永远为false。 - Graviton
3个回答

6

你正在做的是一种简易版的控制反转容器。学习依赖注入控制反转的概念,然后你就可以编写像这样的代码:

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

您可以在运行时(如上所述)或配置文件中配置容器。您可以指定对象生命周期(瞬态、单例、每个线程或自定义)。依赖注入容器旨在帮助对象创建,特别是对于复杂的对象结构和依赖项,使用接口而不是具体类型进行编码(不再使用new ConcreteType()),以及组件配置。
(顺便说一下,从类名中删除后缀Class(因此是UserPost,而不是UserClassPostClass)。)

实际上我工作的地方运用了IoC思想,但我不确定我是否准备好在个人事务中使用如此复杂的东西。我现在正在试图自己弄清楚它,逐步迈出第一步。 - Programmin Tool
看起来这是一个学习概念的绝佳机会,花一天时间静心学习吧。你将会受益于此,终身受益。 - jason

2
正确的检查方法应该是:
if (typeof(TRepository).IsAssignableFrom(typeof(UserClass)))

此外,如果UserClassRepository确实是从IBaseRepository派生出来的,您不需要进行强制转换。
顺便说一句,您为什么要这样做呢?我相信有更好的方法以更可重复的方式实现您想要的目标。

强制转换是必需的,因为 IBaseRepository<UserClass> 本身不能赋值给类型为 IBaseRepository<T> 的变量。 - dtb
有点胡闹,但试图从另一个人的角度设计出易于使用的东西。基本上,这样那个人就不必知道存储库类型,只需知道实体类型。希望IBaseRepository上有最基本和常用的方法,这样就不需要进行转换了。 - Programmin Tool
@dtb - T被限制为IDataEntity,这意味着UserClass必须实现IDataEntity。 - Luke Schafer
1
编程工具 - 你是否在使用依赖注入容器?这是将具体实现抽象化的最佳方式。 - Luke Schafer

1

你并没有明确定义“更好”的含义。然而,我可能会采用一种方法来为每个TClass创建一个自定义属性来定义存储库,并在GetRepository方法中读取此属性。它使用了一些反射,但比大量的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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接