简体   繁体   English

如何创建通用类型字典的基类以将其存储在列表中?

[英]How to create the base class of the generic type dictionary to store it in a list?

I have a lot of methods which return lists of data sets which are represented as the key ( DateTime ) and value (some ValueType or string , I can't know it) pair, and this data sets may have size for about 10 000 items and more. 我有很多方法可以返回以键( DateTime )和值(某些ValueTypestring ,我不知道)对表示的数据集列表,并且这些数据集的大小可能约为10000个项目和更多。 For example: 例如:

public List<DataSet> GetAnyData(...) 
{
    var resultList = new List<DataSet>(); // Create the list for the base class
    resultList.Add(new DoubleDataSet());  // This classes will be filled in this method
    resultList.Add(new StringDataSet());  // See the description for them below
    return resultList;
}

Example of the result list from this method: 此方法的结果列表示例:

ListItem1           ListItem2
Date1    Values1    Date2    Values2
01:00     10.5      02:00     "a"
01:15     20.42     02:15     "b"
01:30     30.01     02:30     "c"

After receiving this data sets I need to process them by different ways (using LINQ). 收到此数据集后,我需要通过不同的方式(使用LINQ)对其进行处理。 And my problem is: how to create the DataSet class? 我的问题是: 如何创建DataSet类?

I tryed a lot of solutions: 我尝试了很多解决方案:

1) To Inherit the DataSet class from Dictionary using generic types: 1)使用泛型类型从Dictionary继承DataSet类:

abstract class DataSet<T> : Dictionary<DateTime, T> {...}

and to create specific classes: 并创建特定的类:

class DoubleDataSet : DataSet<double> {...}
class StringDataSet : DataSet<string> {...}

But the problem is: how to create the base class which I could store in the List of data sets? 但是问题是: 如何创建可以存储在数据集列表中的基类?

2) Create the class of the DataItem of the DataSet and use it in the first solution: 2)创建的类的DataItem的的DataSet以及在所述第一解决方案中使用它:

class DataItem 
{
    public double DoubleValue { get; set; }
    public string StringValue { get; set; }
    // etc
}

class DataSet : Dictionary<DateTime, DataItem> {...}

But the problem is: how to know what property of the DataItem I need to take? 但是问题是: 如何知道我需要获取DataItem什么属性?

3) Store data in the object class: 3)将数据存储在object类中:

public class DataSet : Dictionary<DateTime, object> {...}

public class DoubleDataSet : DataSet
{
    public new double this[DateTime key]
    {
        get { return base[key] as double; }
        set { base[key] = value; }
    }
}

But the problem is: what about boxing and unboxing? 但是问题是: 装箱和拆箱怎么样? If I will have 50 000 values and every value will be converted to object and back to the required type it will spent a lot of time. 如果我有5万个值,并且每个值都将转换为对象并返回所需的类型,则将花费大量时间。 Also using LINQ the type of DataSet value will be an object and I will need to know what type is it. 同样使用LINQ, DataSet值的类型将是一个object ,我将需要知道它的类型。

4) Store the dictionary with the data inside the DataSet class: 4)将带有数据的字典存储在DataSet类中:

public class DataSet
{
    public Dictionary<DateTime, DataItem> Items {get; set;}
}

public class DoubleDataSet : DataSet
{
    public new Dictionary<DateTime, double> Items
    {
        get { return base.Items  // It wouldn't work because there a new dictionary is created
            .ToDictionary(q => q.Key, q => q.Value.DoubleValue); }
        set { base.Items = value
            .ToDictionary(q => q.Key, q => new DataItem(q.Value, null)); }
    }
}

But the problem is: get { return base.Items.ToDictionary(q => q.Key, q => q.Value.DoubleValue); } 但是问题是: get { return base.Items.ToDictionary(q => q.Key, q => q.Value.DoubleValue); } get { return base.Items.ToDictionary(q => q.Key, q => q.Value.DoubleValue); } returns a new instance of the Items dictionary and I can't modify the original list. get { return base.Items.ToDictionary(q => q.Key, q => q.Value.DoubleValue); } 返回Items字典的新实例,我无法修改原始列表。

So help me please how to create the base class of the generic type dictionary to store it in a list? 因此,请帮助我如何创建通用类型字典的基类以将其存储在列表中?

I will be very grateful for any help! 我将非常感谢您的帮助! I know that there is an error of designing (or coding) and I will be glad if anyone will help me to find it! 我知道设计(或编码)有误,如果有人可以帮助我找到它,我将感到高兴! Is it even possible to solve this problem? 甚至有可能解决这个问题吗?

If I understood you correctly, you need to store and process objects of different types in your list, but at the processing time, you don't know on which type of object you are working on. 如果我对您的理解正确,则需要在列表中存储和处理不同类型的对象,但是在处理时,您不知道正在处理哪种类型的对象。

One thing you could try: Since your DataItem class knows what type it is, why don't you let it decide how it gets processed by it implementing the visitor pattern? 您可以尝试做一件事:既然您的DataItem类知道它是什么类型,为什么不让它决定实现访客模式的方式如何处理它呢?

To implement this, you would have to do the following: First, implement your different data items: 为此,您必须执行以下操作:首先,实现您的不同数据项:

// base class you can use in dictionaries
// note that is does not store any data type
class DataItem 
{
    // method called from outside
    // for processing the item
    public abstract void GetProcessed(Processor p);
}

// DataItem which stores a double
class DoubleDataItem  : DataItem
{
    public double Data{get;set;}

    public override void GetProcessed(Processor p)
    {
        p.Process(this);
    }
}

// DataItem which stores a string
class StringDataItem : DataItem
{
    public string Data {get;set}

    public override void GetProcessed(Processor p)
    {
        p.Process(this);
    }
}

Now the information, which type of data is used is only stored in the relevant class. 现在,使用哪种数据类型的信息仅存储在相关的类中。 Every class can also retrieve a processor (or a visitor). 每个类还可以检索处理器(或访问者)。 This processor/visitor can then have different implementations depending on the type it is operating on: 然后,此处理器/访问者可以根据其操作的类型采用不同的实现:

public class Processor
{
    // do processing for double items
    public void Process(DoubleDataItem d);
    // do processing for string items
    public void Process(StringDataItem d);
}

Now when you create your dictionary, the processor will execute the correct code depending on which item it is operating on: 现在,当您创建字典时,处理器将根据其操作的项目执行正确的代码:

var dictionary = new Dictionary<DateTime,DataItem>();
// fill dictionary with data item
var processor = new DoSomethingProcessor();
foreach (var entry in dictionary)
    entry.Value.GetProcessed(processor);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM