如何使用一个对象来存储多种类型的数据 [英] How to use one object to store multiple type of data

查看:167
本文介绍了如何使用一个对象来存储多种类型的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  [可序列化] 
public class Task1Item
{
public int ID {get;组; }
public string Company {get;组; }
------
------
}

[可序列化]
公共类Task2Item
{
public int ID {get;组; }
public string connectTo {get;组; }
public string Port {get;组; }
------
------
}

并将记录插入队列我使用下面的方法

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

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

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

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

这里我只想使用1个队列存储器(因为会有更多的taskitem)一个请告诉我如何将不同的类型结合到一种类型的对象?


$ b

注意:ToBinary& 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();
}

返回字节;
}

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);


$ / code $ / pre
$ b $ p感谢。
<我不熟悉CloudQueueMessage,但从我可以看到它存储byte []这意味着它不关心类型是很好的因为你可以使用你的方法适用于不同的对象,例如:

  var msg = new CloudQueueMessage(item1.ToBinary()); 
var msg1 =新的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);
}
}

公共类Task1处理器:处理器< Task1>
{
.....
}

你从使用反射的队列中获得任务以找到正确的处理器。然后执行它:

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



AllProcessors是系统中所有处理器类型的列表。您可以手动或通过反射扫描从处理器派生的所有类型来生成它。



假设查询是所有处理器将直接从处理器派生,obj是对象表单队列。



希望有所帮助


$ b

编辑



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



正如我所说的,您有两个选择


  1. 例如:
    $ b $ AllProcessors = new List {typeof(Task1Processor),typeof(Task2Processor)}


  2. 使用反射来查找从IP处理器派生的所有类型

    AllProcessors = typeof(IProcessor).Assembly.GetTypes()。其中​​(t => typeof(IProcessor).IsAssignableFrom (t))。ToList();


当然,第二个选项只会从定义IP处理器的程序集中获取类型但你可以很容易地扩展它。

I am dealing to store data in azure queue storage and for that currently i have 2 data types classes as below

  [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; }
        ------
        ------
    }

and for inserting record to queue i am using below methods

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

and i need to read from different queues

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

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

Here i would like to use only 1 queue storage (as there will be more taskitem) so can any one please suggest me how can i combine different types to one type of object?

Note: ToBinary & FromMessage are simple extensions

 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);
            }
        }

Thanks.

解决方案

I'm not familiar with CloudQueueMessage but from what i can see it stores byte[] which means that it doesn't care about types that's good cos you can use your methods for different objects like:

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

With generic method you don't have to specify type compiler will figure it out. Beside with serializer it can just be object.

Now if you convert your FromMessage method to just return object and then you can call it regardless of type.

var obj= FromMessage<object>(msg)

Of course I assume that you need to do some processing on this object for that you could create set of classes for each task type or maybe one generic one if the processing logic can be common. You could do it like that :

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>
{
     .....
}

Then wherever you get task from the queue you use reflection to find correct processor. And then execute it like:

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

AllProcessors is a list of all processors types that you have in the system. You can generate it manually or by reflection scanning all types that derive from Processor<>

Assumption with query are that all processors will directly derive from Processor<> and obj is a object form queue.

Hope that helps

Edit

As requested in comment way to create AllProcessorsList. It would be a static list on Processor abstract class.

As I said you have two options

  1. Do it manually for example:

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

  2. Use reflection to find all types that derive from IProcessor

    AllProcessors = typeof(IProcessor).Assembly.GetTypes().Where(t=>typeof(IProcessor).IsAssignableFrom(t)).ToList();

Of course second option will only get types from assembly where IProcessor was defined but you can extend that very easily.

这篇关于如何使用一个对象来存储多种类型的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆