在抽象基类中定义泛型转换器方法

本文关键字:泛型 转换器 方法 定义 抽象 基类 | 更新日期: 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>.ConverterStaticConverter<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);
    }