在抽象基类中定义泛型转换器方法
本文关键字:泛型 转换器 方法 定义 抽象 基类 | 更新日期: 2023-09-27 18:18:44
我有一个通用的抽象基类为我的逻辑对象,它基本上看起来像这样:
public abstract class LogicClass<TDal>
where TDal : DataClass, new()
{
protected TDal _dalObj;
protected LogicClass(TDal dalObj)
{ _dalObj = dalObj; }
// basic properties and default methods for validating, deleting etc.
}
内部有几个静态方法,用于使用我自己的ORM获取数据。它们是这样的:
protected static List<T> GetList<T>(string whereStatement)
where T : LogicClass<TDal>, new()
{
var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
return dalObjList.ConvertAll(dalObj => new T() { _dalObj = dalObj });
}
大部分工作都很完美,但问题是使用默认构造函数然后设置数据对象,因为在创建数据时,在子类中使用无参数的因素来设置默认属性(例如,在添加客户端对象时将国家设置为默认国家)。
由于我也不能使用使用泛型约束的参数,我想到了这个解决方案:
protected static List<T> GetListT>(Converter<TDal, T> creator, string whereStatement)
where T : LogicClass<TDal>
{
var dalObjList = DataManager.GetCollection<TDal>(whereStatement);
return dalObjList.ConvertAll<T>(creator);
}
可以工作,但是我需要多次使用这个转换器,并且不想多次传递它。
所以我的问题是,有没有一种方法可以只定义一次这个通用转换器?
我想到了这样的东西:
protected abstract Converter<TDal, LogicClass<TDal>> DalConverter;
. .但是让它静态更有意义,这样我就不能再抽象了。
我可以做一个Dictionary<Type, Converter<TDal, LogicClass<TDal>>>
,但我担心这会带来性能损失。
任何想法?
可以将Converter放在泛型类中的静态变量中,并在程序启动时初始化一次。
泛型类为每个泛型类型参数的组合生成一个新类型,每个生成的类型都有一组独立的静态变量。这意味着StaticConverter<Type1,Type2>.Converter
与StaticConverter<Type3,Type4>.Converter
是完全不同的静态变量
class StaticConverter<TDal, T>
where T : LogicClass<TDal>
{
public static Converter<TDal, T> Converter;
}
可以在代码中使用上面的类来检索任何类型集的转换器。比如return dalObjList.ConvertAll<T>(StaticConverter<TDal, T>.Converter);
必须为要用它转换的每个类型初始化(除非您有一些泛型转换代码,否则您可以在静态类中泛型地定义转换器)。
初始化如下所示,需要一次性完成。由于这些变量是静态的,所以它们的值将一直保留到程序结束。
StaticConverter<User, UserLogic>.Converter = v => new UserLogic();
StaticConverter<Client, ClientLogic>.Converter = v => new ClientLogic("Brazil");
编辑
您可以创建如下所示的默认转换器。这为转换器定义了一个默认值,您可以为想要自定义的转换器覆盖该值。
现在您可以确保为所有类型设置了转换器,但仅为与默认值不同的类型提供更新的转换器。
public static T GetLogic<TDal, T>(TDal item)
{
return default(T);
}
class StaticConverter<TDal, T>
where T : LogicClass<TDal>
{
public static Converter<TDal, T> Converter = c => GetLogic<TDal, T>(c);
}