Generics 使用泛型的对象转换

Generics 使用泛型的对象转换,generics,kotlin,design-patterns,type-conversion,converters,Generics,Kotlin,Design Patterns,Type Conversion,Converters,我确实有一个对象转换任务,它会仔细检查我的大脑;) 假设我有三种(或更多)格式的业务对象 class MapA { /*some implementation */ } class MapB { /*some implementation */ } class MapC { /*some implementation */ } 此外,我还有一个“超级对象”,它存储在数据库中,包含MapA、MapB和MapC所有属性的超集 class SuperMap { /* all implemente

我确实有一个对象转换任务,它会仔细检查我的大脑;) 假设我有三种(或更多)格式的业务对象

class MapA { /*some implementation */ }

class MapB { /*some implementation */ }

class MapC { /*some implementation */ }
此外,我还有一个“超级对象”,它存储在数据库中,包含MapA、MapB和MapC所有属性的超集

class SuperMap { /* all implemented properties from all maps */ }
我现在需要能够从和转换到任何地图类型。所以我的想法是指定一个特定的转换器接口,将特定的映射转换为超级映射

interface Converter<F>{

    fun convertFrom(map: F): SuperMap
    fun convertTo(map: SuperMap): F

}
接口转换器{
乐趣转换源(地图:F):超级地图
乐趣转换(地图:超级地图):F
}
然后,多个映射类型的所有者只需实现映射类型超级映射

class MapAConverter: Converter<MapA> {

    override fun convertFrom(map: MapA): SuperMap {
        return SuperMap()
    }

    override fun convertTo(map: SuperMap): MapA {
        return MapA()
    }
}

/* more converters */
类映射转换器:转换器{
覆盖来自(地图:MapA):超级地图{
返回超图()
}
覆盖乐趣转换到(地图:超级地图):地图{
返回MapA()
}
}
/*更多转换器*/
最后,我考虑了一项服务,然后执行以下操作: 如果用户希望将MapA转换为MapC,服务将在内部转换MapA->SuperMap->MapC。。。 这样我就不必把所有可能的组合都编码出来

class ConverterService
{
    private val converters = mutableMapOf<KType, Converter<T>>()

    fun <T>register(converter: Converter<T>){
        this.converters[T::class] = converter
    }

    fun <F, T>Convert(map: F): T{

        // F ... from map
        val conv1 = converters[F::class]
        if (conv1 == null)
            throw Exception("No converter for this type of map")

        // convert to super class
        val sc = conv1.convertFrom(map)

        // T ... to map
        val conv2 = converters[T::class]
        if(conv2 == null){
            throw Exception("No converter for this type of map")
        }

        // convert to desirect class
        return conv2.convertFrom(sc) as T
    }
}
类转换器服务
{
private val converters=mutableMapOf()
乐趣寄存器(转换器:转换器){
this.converters[T::class]=转换器
}
趣味转换(地图:F):T{
//F…来自地图
val conv1=转换器[F::类]
如果(conv1==null)
抛出异常(“此类型的映射没有转换器”)
//转换为超级类
val sc=conv1.convertFrom(映射)
//T…去地图
val conv2=转换器[T::类]
如果(conv2==null){
抛出异常(“此类型的映射没有转换器”)
}
//转换为desirect类
将conv2.convertFrom(sc)返回为T
}
}
但这不起作用

  • 转换器hashmap不知道T

  • val conv1=converters[F::class]告诉我F::class需要重新定义,并希望转换为内联函数。如果我这样做,事情会变得更复杂

  • 我的实施思路如下:

    fun main() {
    
        // register some converters
        var cs = ConverterService()
        cs.register(MapAConverter())
        cs.register(MapBConverter())
        cs.register(MapCConverter())
    
        // input is map a
        val ma = MapA()
    
        // i want map c
        val mc = cs.Convert<MapA, MapC>(ma)
    
    }
    
    fun main(){
    //注册一些转换器
    var cs=ConverterService()
    cs.register(MapAConverter())
    cs.register(MapBConverter())
    cs.register(mapconverter())
    //输入是一张地图
    val ma=MapA()
    //我要地图c
    val mc=cs.换算(ma)
    }
    
    这能以某种方式实现吗?我很高兴得到任何提示/建议

    谢谢大家!

  • 使用
    mutableMapOf()
    (意思)

  • 正如错误消息所说,您需要
    F
    T
    才能使用
    F::class

    inline fun <reified F, reified T> Convert(map: F): T { ... }
    

  • 转换器映射和寄存器功能如何?T::class不是KType.Fixed(没有像Java版本那样检查并假设
    KClass
    extended
    KType
    )。
    private inline fun <reified T> converter(): Converter<T> {
        val result = converters[T::class]
        if (result == null) 
            throw Exception("No converter for ${T::class.qualifiedName}")
        else
            return result as Converter<T>
    }
    
    inline fun <reified F, reified T> Convert(map: F): T {
        // F ... from map
        val conv1 = converter<F>()
        // convert to super class
        val sc = conv1.convertFrom(map)
    
        // T ... to map
        val conv2 = converter<T>()
        // convert to desired class
        return conv2.convertTo(sc)
    }