在C#中动态指定类型

时间:2010-03-17 22:12:06

标签: c# csv casting

我正在创建一个自定义DataSet,但我受到一些限制:

  • 我希望用户指定他们想要存储的数据类型。
  • 我想减少打字,因为我认为它会非常昂贵。
  • 我将在我的应用程序中经常使用数据。

我不知道DataSet中将存储哪种类型的数据,因此我最初的想法是将其设为List object,但我怀疑频繁使用数据和打字的需求将非常昂贵。

基本理念是:

class DataSet : IDataSet
{
    private Dictionary<string, List<Object>> _data;

    /// <summary>
    /// Constructs the data set given the user-specified labels.
    /// </summary>
    /// <param name="labels">
    /// The labels of each column in the data set.
    /// </param>
    public DataSet(List<string> labels)
    {
        _data = new Dictionary<string, List<object>>();
        foreach (string label in labels)
        {
            _data.Add(label, new List<object>());
        }
    }

    #region IDataSet Members

    public List<string> DataLabels
    {
        get { return _data.Keys.ToList(); }
    }

    public int Count
    {
        get { _data[_data.Keys[0]].Count; }
    }

    public List<object> GetValues(string label)
    {
        return _data[label];
    }

    public object GetValue(string label, int index)
    {
        return _data[label][index];
    }

    public void InsertValue(string label, object value)
    {
        _data[label].Insert(0, value);
    }

    public void AddValue(string label, object value)
    {
        _data[label].Add(value);
    }

    #endregion
}

将使用DataSet的具体示例是存储从CSV文件获取的数据,其中第一列包含标签。从CSV文件加载数据时,我想指定类型而不是转换为object。数据可能包含日期,数字,字符串等列。以下是它的样子:

"Date","Song","Rating","AvgRating","User"
"02/03/2010","Code Monkey",4.6,4.1,"joe"
"05/27/2009","Code Monkey",1.2,4.5,"jill"

数据将用于机器学习/人工智能算法,因此我必须非常快速地读取数据。我想尽可能地消除类型转换,因为我不能从'object'转换为每次读取时需要的任何数据类型。

我见过允许用户为csv文件中的每个项目选择特定数据类型的应用程序,所以我试图制作一个类似的解决方案,其中可以为每个列指定不同的类型。我想创建一个通用的解决方案,所以我不必返回List<object>而是List<DateTime>(如果它是DateTime列)或List<double>(如果它是双列的列)。

有什么方法可以实现这一目标吗?也许我的方法是错误的,有没有更好的方法解决这个问题?

2 个答案:

答案 0 :(得分:2)

我建议您尝试现在拥有的东西。也许表现会很好。如果没有,只有这样,你才能考虑进一步优化。

您还可以将每个字段存储为变体对象,如下所示:

struct Variant
{
   string StringValue;
   DateTime DateTimeValue;
   bool BoolValue;
   // ... etc. ...
}

然后你只需要从结构中访问适当的成员,但是这可能会增加内存使用和if语句的开销......

答案 1 :(得分:2)

请记住,DataSet还将行,列等存储为对象。让它们输入类型通常意味着在您键入的数据集中完成转换。

我认为这实际上取决于从csv读取数据会发生什么,但是为了在不事先知道您需要哪种类型的情况下消除转换,我只能想到通过Reflection.Emit动态创建保存数据的类型。

正如杰夫所说,但是施法可能不会杀死你的应用。