Я ищу структуру данных с общим общим назначением в C# для хранения массивов разных типов integer и float. В некоторых случаях целые числа являются битовыми полями, где каждый бит одинаково важен, а потеря точности недопустима. Я нахожу это трудным и беспорядочным из-за системы типа C# и моей нехватки C#.Лучший способ реализовать коллекцию массива разных типов
Проект: Периодические пакеты Ethercat прибывают и преобразуются в структуру (Пакет) и накапливаются как Packet[]
в ходе эксперимента. Каждое поле пакета от Packet[]
преобразуется в массив.
Я считаю, что я ищу способ «обернуть» эти массивы в один тип, чтобы они могли быть частью коллекции. Их упаковка имеет некоторые другие преимущества (присвоение имен, аппаратное обеспечение для коэффициентов шкалы SI и т. Д.), Чтобы облегчить разделение аппаратного обеспечения от последующей реализации.
Моя лучшая «обертка» называется «DataWrapper» (упрощенная ниже), но с ней я столкнулся с неудобными компромиссами при хранении, потерей точности, использованием объекта и количеством кода.
Есть ли «лучший» способ в C#? Мой золотой стандарт - это, по-видимому, тривиальная реализация без очевидных компромиссов в Python с использованием списка списков или numpy.arrays.
Может ли использовать объект? Как? Можно ли поместить весь массив или каждый элемент массива в отдельности (неэффективно)?
Я видел A list of multiple data types? Однако, похоже, много кода и передовых методов программирования для того, что по существу является списком List.
public class DataWrapper
{
private double[] double_array; // backing with double, but it could if I don't use float
private string name;
private double scale_factor_to_SI;
public DataWrapper(string name, double scale_factor, dynamic dynamic_array)
{
this.name = name;
this.scale_factor_to_SI = scale_factor;
this.double_array = new double[dynamic_array.Length];
for (int cnt = 0; cnt < dynamic_array.Length; cnt++)
{
this.double_array[cnt] = (double)dynamic_array[cnt];
}
}
public void Get(out int[] i_array)
{
i_array = this.double_array.Select(item => (int)item).ToArray();
}
public void Get(out long[] i_array)
{
i_array = this.double_array.Select(item => (long)item).ToArray();
}
public double[] GetSI()
{
return this.double_array.Select(item => this.scale_factor_to_SI * (double)item).ToArray();
}
}
public struct Packet // this is an example packet - the actual packet is much larger and will change over time. I wish to make the change in 1 place not many.
{
public long time_uS;
public Int16 velocity;
public UInt32 status_word;
};
public class example
{
public Packet[] GetArrayofPacketFromHardware()
{
return null;
}
public example() {
Packet[] array_of_packet = GetArrayofPacketFromHardware();
var time_uS = array_of_packet.Select(p => p.time_uS).ToArray();
var velocity = array_of_packet.Select(p => p.velocity).ToArray();
var status_bits = array_of_packet.Select(p => p.status_word).ToArray();
List<DataWrapper> collection = new List<DataWrapper> { };
collection.Add(new DataWrapper("time", 1.0e-6, time_uS));
collection.Add(new DataWrapper("velocity", 1/8192, velocity));
collection.Add(new DataWrapper("status", 1, status_bits));
}
}
Почему бы не просто передать пакет [], а не проецировать его значения и передать их? –
Я бы посмотрел на «Список', где 'T' - это класс, в котором есть int, double и float, а также поле типа, в котором указано, какой из них используется. Обычно у меня обычно есть поле «объект» и тип, но вы указали накладные расходы на распаковку. Это проблема, которую вы никогда не решите очень четко на строго типизированном языке, таком как C#. Самое чистое, что вы могли бы потратить на его использование, было бы типом шаблона посетителя для итерации через коллекцию. Тогда вы могли бы, по крайней мере, избежать переключения в поле типа. FWIW. –
Я рассмотрел обертку, которая имеет различную поддержку для каждого типа - имела конструкторы для каждого типа и т. Д. Лучше в некотором роде, но много кода и выход не были очень полезными. Казалось, что должен быть лучший способ. Я был бы в порядке с боксом, если бы был один ящик для каждого массива - не один ящик на элемент. – pathfinder