C#泛型:匹配泛型的更好方法';谁是另一种类型?
更新:没有给出一个很好的例子。希望现在好多了。 有没有比这更好的方法:C#泛型:匹配泛型的更好方法';谁是另一种类型?,c#,generics,typeof,C#,Generics,Typeof,更新:没有给出一个很好的例子。希望现在好多了。 有没有比这更好的方法: (typeof(TRepository) == typeof(UserClass)) 以下是书面形式的用法: public static IBaseRepository<TClass> GetRepository<TClass>() where TClass : IDataEntity { IBaseRepository<TClass> repository = null; i
(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;
}
public static IBaseRepository GetRepository(),其中TClass:IDataEntity
{
IBaseRepository repository=null;
if(typeof(TClass)=typeof(UserClass))
{
repository=(IBaseRepository)新用户类存储库();
}
if(typeof(TClass)=typeof(PostClass))
{
repository=(IBaseRepository)新的后分类存储库();
}
返回存储库;
}
如果像这样的东西经常运行,我希望有比多次运行typeof更好的方法。正确的检查方法是:
if (typeof(TRepository).IsAssignableFrom(typeof(UserClass)))
此外,如果UserClassRepository实际上是从IBaseRepository派生的,则不需要强制转换它
事后想一想,你为什么要这样做?我相信有一种更好的方法可以以更可重复的方式实现你的目标。你在这里做的是穷人的事。扣上安全带,学习和的概念,然后您可以编写如下代码:
IIoCContainer container = new IoCContainer();
container.RegisterType<IBaseRepository<UserClass>, UserClassRepository>();
container.RegisterType<IBaseRepository<PostClass>, PostClassRepository>();
var userClassRepository = container.Resolve<IBaseRepository<UserClass>>();
IIoCContainer=new IoCContainer();
container.RegisterType();
container.RegisterType();
var userClassRepository=container.Resolve();
您可以在运行时(如上所述)或在配置文件中配置容器。您可以指定对象生存期(瞬时、单线程、每线程或自定义)。依赖项注入容器旨在帮助创建对象,特别是对于复杂的对象结构和依赖项,编码到接口而不是具体类型(不再是new ConcreteType()
)和组件配置
(顺便说一句,从你的类名中去掉后缀
Class
(因此User
和Post
,而不是UserClass
和PostClass
)。你还没有真正定义你所说的“更好”是什么意思。不过,我可以采取的一种方法是为定义存储库的每个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;
}
publicstaticibaserepository GetRepository()
TClass:IDataEntity的位置
{
t型=类型(TClass);
RepositoryAttribute属性属性=
(RepositoryAttribute)属性,
typeof(RepositoryAttribute),false;
如果(attr!=null)
{
return(IBaseRepository)Activator.CreateInstance(attr.RepositoryType);
}
返回null;
}
您想实现什么目标typeof(TRepository)==typeof(FiftyPostUser)
应该始终为false。强制转换是必需的,因为不能将IBaseRepository
分配给类型本身为IBaseRepository
的变量。稍微拧一拧,但试图从另一个人的角度设计一些易于使用的东西。基本上,用户不需要知道存储库类型,只需要知道实体类型。希望IBaseRepository上有最基本和最常用的方法,这样就不需要强制转换。@dtb-T仅限于IDataEntity,这意味着UserClass必须实现IDataEntity@programmin工具-您正在使用DI容器吗?这是将具体实现抽象出来的最佳方法。后缀仅用于示例。事实上,我工作的地方有国际奥委会的想法,但我不确定我是否准备好处理任何个人事务上的复杂问题。在这一点上,试着自己去弄清楚,这似乎是一个坐下来花一天时间学习这个概念的好机会。你将在你的余生中收获回报。