Kotlin反射 - 从CSV创建对象

时间:2017-05-20 13:48:17

标签: csv reflection kotlin

我有一个名为Member的数据类:

data class Member(){
    val first_name: String
    val last_name: String
    //30 more

    //a few simple methods
}

我正在尝试导入CSV文件。该文件的每一行都包含我想用来实例化我的会员的字段。

fun ReadCsvFileKotlin() {
    val csvFile = "C:\\Data.csv"
    var memberList = mutableListOf<Member>()
    var reader = File(csvFile).readLines()
    var mbr: Member
    class Member(val p: Int)
    val prop = Member::p
    for(line in reader){
        val mbrProperties = line.split(",")
        for(i in 0..mbrProperties.lastIndex){
            //assign mbrProperties[i] to mbr property
            //mbrProperties[0] = "Bob"
            //mbr.first_name = "Bob"
            //Member::p = mbrProperties[i]
    }
    memberList.add(mbr)
}

我已经完成了我的研究,但是我没有把我所阅读的信息包围起来,只是无法弥合我和我想去的地方之间的差距。

任何建议将不胜感激!我很乐意使用我的示例代码向我介绍或给我示例。

背景:我正在自动化网站测试。在执行每个测试之前,从列表中选择满足必要测试标准的成员,从CSV文件填充。我希望以这种方式创建我的成员对象,以便在测试范围扩展并添加其他标准(和成员类字段)时减少维护开销。

为什么我以我正在做的方式做这些事情?因为我还有很多需要学习的东西......(所以,如果你看到更好的方法,请教育我!)

谢谢!

3 个答案:

答案 0 :(得分:1)

解决这个问题的最简单方法是根本不使用反射。您可以将属性值直接传递给类构造函数:

data class Member(val firstName: String, val lastName: String)

fun readCsvFileKotlin() {
    // ...
    for (line in reader) {
        val mbrProperties = line.split(",") 
        memberList.add(Member(mbrProperties[0], mbrProperties[1]))
    }
}

如果要通过反射设置属性,则需要将它们声明为var而不是val,以便在创建对象后更改它们。然后,您可以使用属性对象上的set方法更改属性值:

data class Member(var firstName: String? = null, var lastName: String? = null)

fun readCsvFileKotlin() {
    // ...
    val prop = Member::firstName
    for (line in reader) { 
        val mbrProperties = line.split(",") 
        val member = Member()
        prop.set(member, mbrProperties[0])
        memberList.add(member)
    }
}

答案 1 :(得分:0)

虽然我确实对yole的反应进行了研究,并且进行了进一步的反思,但我发现了一种更好的方式来处理我的问题。

作为一个经验不足的程序员,我试图为工作使用错误的工具。我想拿一个对象,该对象具有很多功能,它们需要进行许多不同的自动化测试,以模拟用户-无论是否需要测试,我都需要使用每个实例中的代码。

但是我想要的是数据的灵活性。因此,我不再使用具有大量属性的单个对象或多个对象(针对特定数据集的每个自定义),而是使用一个属性。最好的解决方案是键/值对属性。如果Kotlin的演讲语气不佳,我深表歉意。最近两年来,我一直专注于python。字典?

本质上,我剥离了csv的标头,将其作为字典/键值对映射到每一行,然后在实例化对象并将对象添加到列表时添加。如果直接查询数据库而不是使用csv或Excel文件,则类似。

只要我不编写查询来更改结果的表的列名,而且我知道数据库中的列名(它们不会很快改变),并且已经在映射该列到进程和/或gui(或两者)的数据都很好地转换了,而没有反射开销。

答案 2 :(得分:0)

如果您仍然愿意这样做,我创建了自己的CSV库,该库使用反射直接从CSV输入实例化POJO,并且比我测试过的常规解析器Kotlin CSV Stream更好地管理CSV中的错误

我实际上是在放弃传统解析器之后创建它的,因为它们都不满足我的需求。