在抽象基类中定义通用转换器方法

时间:2014-08-20 08:27:30

标签: c# generics

我的逻辑对象有一个通用的抽象基类,基本上看起来像这样:

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 });
    }

大部分工作都很完美,但问题是使用默认构造函数然后设置数据对象,因为无参数ctor在子类中用于在创建数据时设置默认属性(例如,国家/地区设置为默认值)添加客户端对象时的国家/地区。)

由于我也不能使用带有泛型约束的参数的ctor,我想到了这个解决方案:

    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>>>,但我担心它会带来性能损失。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以将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);
    }