如何使用一个对象来存储多种类型的数据

时间:2014-02-25 08:10:02

标签: c# oop generics azure-queues

我正在处理将数据存储在azure队列存储中,目前我有2个数据类型类,如下所示

  [Serializable]
    public class Task1Item
    {
        public int ID { get; set; }
        public string Company { get; set; }
        ------
        ------
    }

   [Serializable]
    public class Task2Item
    {
        public int ID { get; set; }
        public string connectTo{ get; set; }
        public string Port{ get; set; }
        ------
        ------
    }

并且用于将记录插入队列我正在使用以下方法

  // For Task1Item
  CloudQueueMessage msg = new CloudQueueMessage(item1.ToBinary<Task1Item>());
   // For Task2Item
  CloudQueueMessage msg = new CloudQueueMessage(item2.ToBinary<Task2Item>());

我需要从不同的队列中读取

  var item1 = cloudQueueMessage1.FromMessage<Task1Item>();

  var item2 = cloudQueueMessage2.FromMessage<Task2Item>();

这里我只想使用1个队列存储(因为会有更多的任务项目)所以任何人都可以建议我如何将不同类型组合成一种类型的对象?

注意:ToBinary&amp; FromMessage是简单的扩展

 public static byte[] ToBinary<T>(this T dns)
        {
            var binaryFormatter = new BinaryFormatter();
            byte[] bytes = null;
            using (var memoryStream = new MemoryStream())
            {
                binaryFormatter.Serialize(memoryStream, dns);
                bytes = memoryStream.GetBuffer();
            }

            return bytes;
        }

        public static T FromMessage<T>(this CloudQueueMessage cloudQueueMessage)
        {
            var bytes = cloudQueueMessage.AsBytes;
            using (var memoryStream = new MemoryStream(bytes))
            {
                var binaryFormatter = new BinaryFormatter();
                return (T)binaryFormatter.Deserialize(memoryStream);
            }
        }

感谢。

1 个答案:

答案 0 :(得分:2)

我不熟悉CloudQueueMessage,但从我所看到的内容中存储了byte [],这意味着它并不关心那些可以将你的方法用于不同对象的好成本喜欢:

var msg = new CloudQueueMessage(item1.ToBinary());
var msg1 = new CloudQueueMessage(item2.ToBinary());

使用泛型方法,您不必指定类型编译器就能解决它。除了序列化器,它可以只是对象。

现在,如果将FromMessage方法转换为只返回对象,那么无论类型如何都可以调用它。

var obj= FromMessage<object>(msg)

当然我假设您需要对此对象进行一些处理,因为您可以为每个任务类型创建一组类,或者如果处理逻辑可以是常见的,则可以创建一个通用类。你可以这样做:

public interface IProcessor
{
    void Process(object obj);
}

public abstract class Processor<T>, IProcessor
{
    public void Process(T obj);
    public void Process(object obj)
    {
        Process((T)obj);
    }
}

public class Task1Processor:Processor<Task1>
{
     .....
}

然后,无论您从队列中获取任务,都可以使用反射来查找正确的处理器。然后执行它:

var processorType = AllProcessors.FirstOrDefault(p=>p.BaseType.GetGenericParameters()[0]==obj.GetType())
var processor = (IProcessor)Activator.CreateInstance(processorType);
processor.Process(obj);

AllProcessors是系统中所有处理器类型的列表。您可以手动生成它,也可以通过反射扫描从处理器&lt;&gt;

派生的所有类型

对查询的假设是所有处理器将直接从处理器&lt;&gt;得到。和obj是一个对象形式队列。

希望有所帮助

修改

按照评论的方式请求创建AllProcessorsList。它将是处理器抽象类的静态列表。

正如我所说,你有两个选择

  1. 手动执行,例如:

    AllProcessors = new List {typeof(Task1Processor),typeof(Task2Processor)}

  2. 使用反射查找从IProcessor

    派生的所有类型

    AllProcessors = typeof(IProcessor).Assembly.GetTypes()。Where(t =&gt; typeof(IProcessor).IsAssignableFrom(t))。ToList();

  3. 当然第二个选项只能从已定义IProcessor的程序集中获取类型,但您可以非常轻松地扩展它。