Return 基于泛型参数的具体对象
Return concrete objects based on generic parameter
我正在与第三方 class 合作,如下所示:
public class RepositoryGroup
{
public StringRepository StringRepository { get; set; } //implements IRepository<string>
public IntRepository IntRepository { get; set; } //implements IRepository<int>
}
我想创建一个通用的 GetRepository 方法:
public IRepository<T> GetRepository<T>(RepositoryGroup group)
{
if (typeof(T) == typeof(string)) return (IRepository<T>)group.StringRepository;
if (typeof(T) == typeof(int)) return (IRepository<T>)group.IntRepository;
}
但这行不通,因为编译器 "smart" 不足以根据条件注意到 T
是 string
。
有没有办法强制编译器识别或忽略它?我知道我可以通过反思来做到这一点,但我宁愿不这样做(主要是为了可读性)。
这不能直接与泛型一起使用,因为 C# 中的泛型不像 C++ 模板那样支持专门化。
最简单的解决方案是执行运行时类型转换,这应该是安全的,因为您已经测试了 T
的值 - 因此
if (typeof(T) == typeof(string)) return group.StringRepository as IRepository<T>;
if (typeof(T) == typeof(int)) return group.IntRepository as IRepository<T>;
更常见和更彻底的解决方案是设计一个本身不是通用的基本接口,然后从通用接口实现该接口。例如,这是在具有 IEnumerable
and IEnmerable<T>
接口的 .NET 框架中完成的。
因此:
IRepository<T> : IRepository
...
public IRepository GetRepository<T>(RepositoryGroup group)
我正在与第三方 class 合作,如下所示:
public class RepositoryGroup
{
public StringRepository StringRepository { get; set; } //implements IRepository<string>
public IntRepository IntRepository { get; set; } //implements IRepository<int>
}
我想创建一个通用的 GetRepository 方法:
public IRepository<T> GetRepository<T>(RepositoryGroup group)
{
if (typeof(T) == typeof(string)) return (IRepository<T>)group.StringRepository;
if (typeof(T) == typeof(int)) return (IRepository<T>)group.IntRepository;
}
但这行不通,因为编译器 "smart" 不足以根据条件注意到 T
是 string
。
有没有办法强制编译器识别或忽略它?我知道我可以通过反思来做到这一点,但我宁愿不这样做(主要是为了可读性)。
这不能直接与泛型一起使用,因为 C# 中的泛型不像 C++ 模板那样支持专门化。
最简单的解决方案是执行运行时类型转换,这应该是安全的,因为您已经测试了 T
的值 - 因此
if (typeof(T) == typeof(string)) return group.StringRepository as IRepository<T>;
if (typeof(T) == typeof(int)) return group.IntRepository as IRepository<T>;
更常见和更彻底的解决方案是设计一个本身不是通用的基本接口,然后从通用接口实现该接口。例如,这是在具有 IEnumerable
and IEnmerable<T>
接口的 .NET 框架中完成的。
因此:
IRepository<T> : IRepository
...
public IRepository GetRepository<T>(RepositoryGroup group)