【问题标题】:Creating a class with a generic csv reader via a method通过方法创建具有通用 csv 阅读器的类
【发布时间】:2017-10-05 12:24:16
【问题描述】:

提醒一下,我是 stackoverflow 的新手,所以如果我不擅长寻找解决方案,请告诉我。

我有一个类库,它能够根据类的公共成员读取 csv 文件,然后分配它们。但是,当我想调用/调用该方法时,我不知道避免长时间切换或 if else 的方法。

这是我目前的使用方式:

public class DataSetup
{
    List<object> ObjList = new List<object>();

    public DataSetup(string file)
    {
        switch (file)
        {
            case "Persons.csv":
                AssignCsvData<Person>(file);
                break;
            case "Address.csv":
                AssignCsvData<Address>(file);
                break;
        }
    }

    public void AssignCsvData<T>(string file) where T : CsvableBase, new()
    {
        var cr = new CsvReader<T>();
        var csvObjs = cr.Read(file);
        foreach (var obj in csvObjs)
        {
            ObjList.Add(obj);
        }
    }

}

切换没有“完成”,因为我希望有更好的方法。 那么有没有办法在没有开关的情况下调用AssignCsvData?

到目前为止,我已经尝试将类型作为构造函数的参数,但是当它是变量时,我不能将其用作类型。

【问题讨论】:

  • 我认为另一种方法是使用带有 csvName,Type 的字典并使用 Activator 创建通用类型,但这会导致很多问题,我认为您最好使用 switch。
  • 为什么要避免switch语句?可以使用 enum 来声明不同的类型,这样就可以避免打开一个字符串,这样比较安全。
  • 我主要是想避免它,因为我很懒。我也希望它是完全通用的。不过我正处于学习阶段,那么至少在这种情况下使用开关实际上更好吗?

标签: c# csv generics c#-6.0


【解决方案1】:

如果文件名总是代表一个类。在您的情况下,Persons.csv 和 Person 之间存在不匹配,但如果说它们确实匹配,那么以下可以使用反射而不是 switch 语句来工作:

var type = Type.GetType(Path.GetFileNameWithoutExtension(file));

var method = typeof(Processor)
        .GetMethod("AssignCsvData")
        .MakeGenericMethod(type);

method.Invoke(new Processor(), file);   

注意:如果您想在 LinqPad 中对此进行测试,请不要忘记使用“UserQuery+”命名空间来获取类型。即:

var type = Type.GetType($"UserQuery+{Path.GetFileNameWithoutExtension(file)}");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 2014-03-15
    相关资源
    最近更新 更多