Initializing an array of structs that contain a array of bytes - c#

struct a
{
int x;
int y;
byte[] z;
}
var b = new a[] {{0, 0, {0, 0, 0}}, {1,1, {1,1,1}}};
I want to initialize an array of a struct each of which contains an array of bytes. I also tried:
var b = new a[] {{0, 0, new byte[] {0, 0, 0}}, {1,1, new byte[] {1,1,1}}};

A constructor will make it more arranged and readable:
struct a
{
int x;
int y;
byte[] z;
public a(int xv, int yv, byte[] zv)
{
x = xv;
y = yv;
z = zv;
}
}
public void Initialize()
{
var b = new a[] {new a(0,0,new byte[] { 0,0,0}),
new a(1,1,new byte[] { 1,1,2})};
}
Another way According to your Comment
1. if you declare the access modifier of the struct fields as public you
will be able to initialize them using object initializer and not
with constructor (constructor is a method).
2. you can use static class and immediately call that object
3. make b global and public (var is only local keyword) in order to call it
from outside (i would use a more descriptive name then b).
full example:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("y value of index 1 is: {0}", General.b[1].y);
Console.ReadLine();
}
}
public static class General
{
public static a[] b = new a[] { new a() { x = 0, y = 0, z = new byte[] { 0, 0, 0 }},
new a() { x = 1, y = 1, z = new byte[] { 1, 1, 1 }}
};
public struct a
{
public int x;
public int y;
public byte[] z;
}
}

Use a regular constructor with some values, and write the array contents later:
public struct A
{
const int Size = 256;
// mutable structs are evil.
public int x, y;
// At least make the arrays (not the contents) readonly
readonly public byte[] a;
readonly public byte[] b;
public A(int x, int y)
{
this.x = x;
this.y = y;
this.a = new byte[Size];
this.b = new byte[Size];
}
}
class Program
{
static void Main(string[] args)
{
var x = new A(48, 64);
var y = new A(32, 24);
x.a[4] = 1;
y.b[127] = 31;
}
}

Related

Using Indexers for multiple Arrays in the class c#

I have two arrays in my Base class, and I want to create Indexers that can be used in both of them, attached below is an MVCE of what I am trying to do.
class Indexer
{
private string[] namelist = new string[size];
private char[] grades = new string[size];
static public int size = 10;
public IndexedNames() {
for (int i = 0; i < size; i++){
namelist[i] = "N. A.";
grades[i] = 'F';
}
}
public string this[int index] {
get {
string tmp;
if( index >= 0 && index <= size-1 ) {
tmp = namelist[index];
} else {
tmp = "";
}
return ( tmp );
}
set {
if( index >= 0 && index <= size-1 ) {
namelist[index] = value;
}
}
}
In the above coed if you comment out the lines private char[] grades = new string[size]; and grades[i] = 'F'; then you can use the indexers as object_name[i] but I want to be able to access both namelist and grades by indexers.
Note : I cannot use structures to wrap them together as in my application, there size may not always be same.
Is this possible or I would need to go around with some hack.
Edit
I am looking for something like names.namelist[i] and names.grades[i], or some statements that I can access them separately. Also Indexer logic is not consistent, and even size varies in some arrays, that was skipped here to aid simplicity in MVCE.
Sorry, no-can-do.
Although Indexers can be Overloaded and can have more than one formal parameter, you can't make two variations based on the same Parameter in the same class. This is a Language Limitation (or blessing).
Indexers (C# Programming Guide)
However, this should lead you to several options.
You can just make use of C#7. Ref returns
Starting with C# 7.0, C# supports reference return values (ref
returns). A reference return value allows a method to return a
reference to a variable, rather than a value, back to a caller. The
caller can then choose to treat the returned variable as if it were
returned by value or by reference. The caller can create a new
variable that is itself a reference to the returned value, called a
ref local.
public ref string Namelist(int position)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (position < 0 || position >= array.Length)
throw new ArgumentOutOfRangeException(nameof(position));
return ref array[position];
}
...
// Which allows you to do funky things like this, etc.
object.NameList(1) = "bob";
You could make sub/nested classes with indexers
That's to say, you could create a class that has the features you need with indexers, and make them properties of the main class. So you get something like you envisaged object.Namelist[0] and object.Grades[0].
Note : in this situation you could pass the arrays down as references and still access them in the main array like you do.
Example which includes both:
Given
public class GenericIndexer<T>
{
private T[] _array;
public GenericIndexer(T[] array)
{
_array = array;
}
public T this[int i]
{
get => _array[i];
set => _array[i] = value;
}
}
Class
public class Bobo
{
private int[] _ints = { 2, 3, 4, 5, 5 };
private string[] _strings = { "asd","asdd","sdf" };
public Bobo()
{
Strings = new GenericIndexer<string>(_strings);
Ints = new GenericIndexer<int>(_ints);
}
public GenericIndexer<string> Strings ;
public GenericIndexer<int> Ints ;
public void Test()
{
_ints[0] = 234;
}
public ref int DoInts(int pos) => ref _ints[pos];
public ref string DoStrings(int pos) => ref _strings[pos];
}
Usage:
var bobo = new Bobo();
bobo.Ints[1] = 234;
bobo.DoInts(1) = 42;
I think only a two parameter indexer can achieve what you want.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace ConsoleApp1
{
class MyClass
{
protected static Dictionary<string, FieldInfo[]> table = new Dictionary<string, FieldInfo[]>();
static public int size = 10;
protected char[] grades = new char[size];
public object this[string name, int index]
{
get
{
var fieldInfos = table[this.GetType().FullName];
return ((Array)fieldInfos.First((x) => x.Name == name).GetValue(this)).GetValue(index);
}
set
{
var fieldInfos = table[this.GetType().FullName];
((Array)fieldInfos.First((x) => x.Name == name).GetValue(this)).SetValue(value, index);
}
}
static void Main()
{
var names = new MyChildClass();
names[DataColumns.Grades, 1] = 'S';
names[DataColumns.NameList, 9] = "W.S";
}
}
class MyChildClass : MyClass
{
private string[] namelist = new string[size];
static MyChildClass()
{
var t = typeof(MyChildClass);
table.Add(t.FullName, t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance));
}
public MyChildClass()
{
for (int i = 0; i < size; i++)
{
namelist[i] = "N. A.";
grades[i] = 'F';
}
}
}
static class DataColumns
{
public static string NameList = "namelist";
public static string Grades = "grades";
}
}
Maybe something like this:
class Indexer
{
private string[] namelist = new string[size];
private string[] grades = new string[size + 1]; // size +1 to indicate different
// size
static public int size = 10;
public void IndexedNames()
{
for (int i = 0; i < size; i++)
{
namelist[i] = "N. A.";
grades[i] = "F";
}
}
public string this[int i, int j]
{
get
{
string tmp;
// we need to return first array
if (i > 0)
{
tmp = namelist[i];
}
else
{
tmp = grades[i];
}
return (tmp);
}
set
{
if (i > 0)
{
namelist[i] = value;
}
else grades[i] = value;
}
}
}

How to sort array of objects by fields without linq and other classes? (in C#)

Here is example of how to sort array of objects by it's fields. I need to create function which will do same thing but WITHOUT Linq, Generics or any other classes.
p.s You can add methods in Test class to compare fields.
using System;
using System.Linq;
class Test {
public int Count;
public int Sum;
}
class Program {
static void Main() {
Test a1 = new Test() {
Count = 1 ,
Sum = 20
};
Test a2 = new Test() {
Count = 2 ,
Sum = 10
};
Test a3 = new Test() {
Count = 3 ,
Sum = 30
};
var arr = new Test[] { a1, a2, a3};
var result = arr.OrderBy(n => n.Count).ToList();
foreach (var item in result) {
Console.WriteLine(item.Count);
}
}
static void MyOrder() {
//function which will sort passed array of objects by fields
}
}
One method is to use Array.Sort() static method. But if you want to use it, you class must implement IComparable interface, for example:
class Test : IComparable
{
public int Count;
public int Sum;
public int CompareTo(object obj)
{
if (!(obj is Test))
throw new ArgumentException("You can't compare two objects of different types!");
var test = (Test)obj;
if (test.Count < this.Count) return 1;
else if (test.Count > this.Count) return -1;
else return 0;
}
}
And then code would become:
var arr = new Test[] { a1, a3, a2 };
Array.Sort(arr);
EDIT:
If you want to change ordering field at runtime, you can use IComparer interface as folloing:
public class Test
{
public int Count;
public int Sum;
}
public class TestComparerBySum : IComparer<Test>
{
public int Compare(Test x, Test y)
{
if (x.Sum > y.Sum) return 1;
else if (x.Sum < y.Sum) return -1;
else return 0;
}
}
public class TestComparerByCount : IComparer<Test>
{
public int Compare(Test x, Test y)
{
if (x.Count > y.Count) return 1;
else if (x.Count < y.Count) return -1;
else return 0;
}
}
And use it in code like this:
var arr = new Test[] { a3, a2, a1 };
Array.Sort(arr, new TestComparerBySum());
Array.Sort(arr, new TestComparerByCount());

How to use a string to invoke a function via and interface

So here's a simple example put up where I can add and subtract based on a string input. Then instead of calculating on the spot I wanted to create functions so that I can create an interface. The idea: Use the to refer to anything. I want to put and objects in there, with a uniform way of calling the objects (e.g. they all have an interface that exposes a Compute() method) So here are my two pieces of code that I can't get to mesh to complete this.
public class Calculator
{
private Dictionary<string, Func<float,float,float>> _map = new Dictionary<string, Func<float,float,float>>
{
{ "add", (a,b) => a+b },
{ "subtract", (a,b) => a-b },
{ "multiply", (a,b) => a*b },
{ "divide", (a,b) => a/b },
};
public float Compute(float[] numbers, string opCode)
{
var operation = _map[opCode];
float accumulator = numbers[0];
foreach (var n in numbers.Skip(1))
{
accumulator = operation(accumulator, n);
}
return accumulator;
}
}
public class Program
{
public static void Main()
{
var c = new Calculator();
Console.WriteLine(c.Compute( new float[] { 2,2 }, "add"));
Console.WriteLine(c.Compute( new float[] { 3,3 }, "multiply"));
Console.WriteLine(c.Compute( new float[] {-2,2 }, "subtract"));
Console.WriteLine(c.Compute( new float[] { 9,3 }, "divide"));
}
}
that demonstrates what outputs I'm looking for. Now creating the interface how do I use it in a similar fashion to the above framework?
public interface ICalculate
{
int Calculate(int x, int y);
}
public class Add : ICalculate
{
#region ICalculate Members
public int Calculate(int x, int y)
{
return x + y;
}
#endregion
}
public class Subtract : ICalculate
{
#region ICalculate Members
public int Calculate(int x, int y)
{
return x - y;
}
#endregion
}

Cannot implicitly convert type 'uint' to 'T' (from class template) in List

I am doing converting code to C# from C++ but having some problem for the vector part for generics variable issue.I am beginner in C#.
C++ code:
Pvec(){}
Pvec(size_t n): p(n) {}
Pvec(size_t n, T v): p(n, v) {}
template<class T2>
Pvec(const vector<T2>& v) {
for (int i = 0; i < p.size(); ++i)
p[i] = v[i];
}
template<class T2>
Pvec(const Pvec<T2>& v) {
p.resize(v.size());
for (int i = 0; i < v.size(); ++i)
p[i] = v[i];
}
C# code (converting by me but facing a lot of error):
public class Pvec <T>
{
private List<T> p = new List<T>();
public Pvec()
{
}
public Pvec(uint n)
{
this.p = n;
}
public Pvec(uint n, T v)
{
this.p = new List<T>(n, v);
}
//ORIGINAL LINE: template<class T2>
public Pvec<T2>(List<T2> v)
{
for (int i = 0; i < p.Count; ++i)
{
p[i] = v[i];
}
}
//ORIGINAL LINE: template<class T2>
public Pvec<T2>(Pvec<T2> v)
{
p.resize(v.size());
for (int i = 0; i < v.size(); ++i)
{
p[i] = v[i];
}
}
How about i have more than two template in class?
There are a couple of problems with your code. First of all, you're trying to assign a uint to a List<T>, where no such conversion exists. Furthermore, you're trying to set List<T> with a constructor taking a count which is of type int and not uint. What you need to do:
Use this.p = new List<T>() which uses the List<T> constructor
Either accept an int, or cast the uint to an int.
I would leave the declaration of p uninstantiated, as you initialize it in the constructor anyway.
Use constructor chaining
public class Pvec<T>
{
private List<T> p;
private const int DefaultVectorSize = 4;
public Pvec() : this(DefaultVectorSize, default(T))
{
}
public Pvec(uint n) : this((int)n, default(T))
{
}
public Pvec(uint n, T v)
{
var capacity = (int)n;
p = EqualityComparer<T>.Default.Equals(v, default(T)) ?
new List<T>(capacity) { v } : new List<T>(capacity);
}
}
Or:
public class Pvec<T>
{
private List<T> p;
private const int DefaultVectorSize = 4;
public Pvec() : this(DefaultVectorSize, default(T))
{
}
public Pvec(int n) : this(n, default(T))
{
}
public Pvec(int n, T v)
{
p = EqualityComparer<T>.Default.Equals(v, default(T)) ?
new List<T>(n) { v } : new List<T>(n);
}
}
Side note - Give you parameters meaningful names.
This is wrong:
public Pvec(uint n)
{
this.p = n;
}
You are trying to assign a uint to a list. In the C++ code the uint is the size of the vector. You need to mirror this in C#. You could do it this way:
public Pvec(int n)
{
p = new List<T>(n);
}
Note - I changed from uint to int since this is the type for the list constructor. You could leave it as a uint and handle the conversion in the constructor but with the warning that you could pass in a value that would overflow.

How to copy a 1D array to 3D array efficiently in C#?

I have a linear array which I need to reshape as of a stack of 2D data. In this particular case, the stack only contains one element so the output should be an array with dimensions (height, width, 1).
This is related to a previous question, where I was asking about the same operation in the other direction (3D to 1D).
What is the fastest way to map this data to a 3D array?
I was planning to take the following approach:
public static byte[, ,] ToBuffer3D<TDepth>(this byte[] buffer, int w, int h)
{
byte[, ,] buff3D = new byte[h, w, 1];
for (int i = 0; i < buffer.Length; i++)
{
buff3D[(int)Math.Floor(i / (double)w), i % w, 0] = buffer[i];
}
return buff3D;
}
But it seems like it might be possible to take advantage of how the data is already stored in memory to copy more than one element at a time. Is there some other mapping approach that could be employed in C#?
This is likely to be somewhat faster:
public static byte[,,] ToBuffer3Da(this byte[] buffer, int w, int h)
{
byte[,,] buff3D = new byte[h, w, 1];
Buffer.BlockCopy(buffer, 0, buff3D, 0, h*w);
return buff3D;
}
if you use the base class and implementation defined below, you have a class that supports both linear and dimensional indexing at the same time. No conversion or copying is necessary.
Use it like this,
var matrix = new DecomposedMatrix<byte>(10, 10, 10)
foreach(var b int matrix)
{
...
}
for (var i = 0; i < matrix.Count; i++)
{
...
var item = matrix[i];
...
}
for (var x = 0; x < matrix.H; x++)
for (var y = 0; y < matrix.W; y++)
for (var z = 0; z < matrix.D; z++)
{
...
var item = matrix[x, y, z];
...
}
classes follow ...
public abstract class DecomposedMatrix
{
private readonly int h;
private readonly int w;
private readonly int d;
protected DecomposedMatrix(int h, int w, int d)
{
this.h = h;
this.w = w;
this.d = d;
}
public int W
{
get
{
return this.w;
}
}
public int D
{
get
{
return this.d;
}
}
public int H
{
get
{
return this.h;
}
}
protected int DereferenceCoordinates(int x, int y, int z)
{
if (x >= this.H || y >= this.W || z >= this.D)
{
throw new IndexOutOfRangeException();
}
if (x < 0 || y < 0 || z < 0)
{
throw new IndexOutOfRangeException();
}
return z + (y * this.D) + (x * this.W * this.D);
}
}
and the implementation
public class DecomposedMatrix<T> : DecomposedMatrix, IReadOnlyList<T>
{
private readonly IList<T> data;
public DecomposedMatrix(int h, int w, int d)
: base(h, w, d)
{
this.data = new T[h * w * d];
}
public T this[int index]
{
get
{
return this.data[index];
}
set
{
this.data[index] = value;
}
}
public T this[int x, int y, int z]
{
get
{
return this.data[this.DereferenceCoordinates(x, y, z)];
}
set
{
this.data[this.DereferenceCoordinates(x, y, z)] = value;
}
}
public int Count
{
get
{
return this.data.Count;
}
}
public IEnumerator<T> GetEnumerator()
{
return this.data.GetEnumerator();
}
public IEnumerator IEnumerable.GetEnumerator()
{
return this.data.GetEnumerator();
}
}

Categories