如何返回不同类型的数组? [英] How to return different types of arrays?

查看:265
本文介绍了如何返回不同类型的数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中遇到的高级问题是制作描述机器人控制网络数据包(Ethercat)的数据结构的单一副本,然后使用该单个数据结构从数据包集合中提取数据。



当尝试使用累积数据包中的数据时,会出现问题,因为数据结构的隐式重复与指定类型的转换或调用函数。为了协助解释目标,我已经编写了一个python程序,它可以帮助我确定是否可以在C#中执行此操作。



C#中对我的挑战是单个函数get_vector,它返回变量数值类型的均匀集合。这种类型是在数据包结构中定义的,而python可以在不定义重新定义数据结构的情况下使用。

  import struct 

#完整包的描述
class PACKET_STRUCTURE:

#给出一个字段名称和一个数据包列表,返回一个向量
#这是函数似乎不可能在C#中,因为返回的类型更改
def get_vector(self,name,packet_list):
#通过向量的名称定位数据包定义
result = [ x for self.packet_def如果x.field_name == name]

#没有错误检查,pos包含定义的位置
pos = result [0] .position;

#解码(编码)数据包列表中的所有pacckets - 返回一个[time_sec,status,position
#在C#中的列表,这个步骤类似于使用Marshal.PtrToStructure从byte []到一个struct
decoded_pa​​cket_list = [struct.unpack(self.fmt_str,packet)for packet in packet_list];

#从decode_packets列表中,将所需字段提取到自己的列表中
vector = [decode [pos] for decode in decoded_pa​​cket_list]

#in C#这类似于:
#var CS_vector = decode_packet_list.Select(item => item.field_name).ToArray();
#到目前为止在C#中没有重复的数据包结构。
#,但在这一点之后,假设我将CS_vector转换为对象并返回 -
#来使用该对象,我还没有想出如何避免将其转换为某种类型的数组
#eg double [],int32 []
return vector

def __init __(self):
self.packet_def = list();
self.fmt_str =<;
self.cnt = 0;

#将单个项目的描述添加到结构
def add(self,struct_def):
struct_def.position = len(self.packet_def);
self.packet_def.append(struct_def);
self.fmt_str + = struct_def.type;

#根据定义的结构创建一个基于计数器的简单数据包
def make_packet(self):
vals = [self.cnt * 10 + x for x in range (0,len(self.packet_def))];
self.cnt + = 1;
pk = apply(struct.pack,[self.fmt_str] + vals)
#print len(pk),[%c%x for p in pk]
return pk

def get_names(self):
return [packet_items.field_name for packet_items in self.packet_def];


#包内单个字段的描述
class PACKET_ITEM:
def __init __(self,field_name,type):
self.field_name = field_name
self.type = type;
#self.offset = 0;
self.position = 0;


if __name__ ==__main__:

INT32 =l;
UINT16 =H;
FLOAT =f;

packet_def = PACKET_STRUCTURE();

#创建一个示例数据包结构 - 这是仲裁,可以是任何东西 - 甚至可以从文件中读取
#这个定义是数据包结构的唯一定义
这里的#更改需要在程序的其他地方没有改变
packet_def.add(PACKET_ITEM(time_sec,FLOAT))
packet_def.add(PACKET_ITEM(status,UINT16))
packet_def。添加(PACKET_ITEM(position,INT32))

#创建数据包列表
pk_list = list()
为范围(0,10)中的cnt:
pk_list.append(packet_def.make_packet());

#######################################
#无需复制即可获取向量结构
#eg no int32 [] position =(int32 [])get_vector()

name_list = packet_def.get_names();
在name_list中的名称:
vector = packet_def.get_vector(name,pk_list);
打印名称,向量


解决方案

答案是将数组存储在类型为的集合中列出< dynamic>



返回从收集也应该是动态的。



这是更完整的答案我的错误理解的问题,这个人试图澄清。


The high level problem I'm having in C# is to make a single copy of a data structure that describes a robot control network packet (Ethercat), and then to use that single data structure to extract data from a collection of packets.

The problem arises when attempting to use the data from the accumulated packets as there is implicit duplication of the data structure with casting or calling functions that specify the type. To assist in explaining the goal, I've written a python program that does what I want and would like help to determine if its possible to do this in C#.

The challenge for me in C# is the single function "get_vector" which returns a homogeneous collection of a variable numerical type. This type is defined in the packet structure and in python can be used without defining re-defining the data structure.

import struct

# description of the complete packet
class PACKET_STRUCTURE :

# given a field name and a list of packets, return a vector
# this is the function that seems impossible in C# because the type of what is returned changes
def get_vector(self, name, packet_list):
    # locate the packet definition by the name of the vector
    result = [x for x in self.packet_def if x.field_name == name]

    # without error checking, pos contains the location of the definition
    pos = result[0].position;

    # decode ALL the pacckets in the (encoded) packet list - returning a list of [time_sec, status, position
    # in C# this step is similar to  using Marshal.PtrToStructure to transform from byte[] to a struct
    decoded_packet_list = [struct.unpack(self.fmt_str, packet) for packet in packet_list];

    # from the list of decoded_packets, extract the desired field into its own list          
    vector = [decode[pos] for decode in decoded_packet_list]

    # in C# this is similar to:
    # var CS_vector = decode_packet_list.Select(item => item.field_name).ToArray();
    # so far in C# there is no duplication of the packet structure.
    # but after this point, assume I cast CS_vector to object and return it - 
    # to use the object, I've not figured out how to avoid casting it to some type of array
    # eg double[], int32[]                        
    return vector        

    def __init__(self):
        self.packet_def = list();
        self.fmt_str = "<";
        self.cnt = 0;

    # add description of single item to the structure
    def add(self, struct_def) :
        struct_def.position = len(self.packet_def);
        self.packet_def.append(struct_def);
        self.fmt_str += struct_def.type;                

    # create a simple packet based on a counter based on the defined structure
    def make_packet(self):
        vals = [self.cnt*10+x for x in range(0, len(self.packet_def))];
        self.cnt += 1;
        pk = apply(struct.pack, [self.fmt_str] + vals)
        # print len(pk), ["%c" % x for x in pk]
        return pk

    def get_names(self):
        return [packet_items.field_name for packet_items in self.packet_def];


# the description of a single field within the packet
class PACKET_ITEM  :
    def __init__(self, field_name, type):
        self.field_name = field_name
        self.type = type;
        # self.offset = 0;
        self.position = 0;


if __name__ == "__main__" :

    INT32 = "l";
    UINT16 = "H";
    FLOAT = "f";

    packet_def = PACKET_STRUCTURE();

    # create an example packet structure - which is arbituary and could be anything - it could even be read from a file
    # this definition is the ONLY defintion of the packet structure
    # changes here require NO changes elsewhere in the program
    packet_def.add(PACKET_ITEM("time_sec", FLOAT))
    packet_def.add(PACKET_ITEM ("status",UINT16))
    packet_def.add(PACKET_ITEM ("position",INT32))

    # create a list of packets
    pk_list = list()
    for cnt in range(0,10) :
        pk_list.append(packet_def.make_packet());

    ################################
    # get the vectors without replicating the structure
    # eg no int32[] position = (int32[])get_vector()

    name_list = packet_def.get_names();
    for name in name_list :
        vector = packet_def.get_vector(name, pk_list);
        print name, vector

解决方案

The answer is to store the arrays in a collection of type List<dynamic>

The return type of function that returns elements from the collection should also be dynamic.

Here is the more complete answer to my miss-understood question which this one attempted to clarify.

这篇关于如何返回不同类型的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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