I have the following piece of code I wish to do without using the Bitmap Class
I am not sure where to start can someone give me some code samples or examples to work from
public class PgmImage
{
public int Width { get; set; }
public int Height { get; set; }
public int MaxVal { get; set; }
public byte[][] Pixels { get; private set; }
public PgmImage(int width, int height, int maxVal,
byte[][] pixels)
{
this.Width = width;
this.Height = height;
this.MaxVal = maxVal;
this.Pixels = pixels;
}
}
private static Bitmap MakeBitmap(PgmImage pgmImage, int mag)
{
int width = pgmImage.Width * mag;
int height = pgmImage.Height * mag;
Bitmap result = new Bitmap(width, height);
Graphics gr = Graphics.FromImage(result);
for (int i = 0; i < pgmImage.Height; ++i)
{
for (int j = 0; j < pgmImage.Width; ++j)
{
int pixelColor = pgmImage.Pixels[i][j];
Color c = Color.FromArgb(pixelColor, pixelColor, pixelColor);
SolidBrush sb = new SolidBrush(c);
gr.FillRectangle(sb, j * mag, i * mag, mag, mag);
}
}
return result;
}
The reason behind this is that NetStandard doesn't have the Bitmap class to use
Related
i'm trying to convert a string from file to 2d array. Is it possible to make the array dynamic? And how can i return the array, so i can work with it? I'm really confused.
public interface IMazeLoader
{
Maze LoadMaze(string src);
}
class MazeLoader : IMazeLoader
{
public Maze LoadMaze(string filepath)
{
var width = 5;
var height = 5;
var map = new char[width, height];
var file = new StreamReader(filepath);
string line;
var lineCount = 0;
while ((line = file.ReadLine()) != null)
{
if (lineCount < height)
{
for (int i = 0; i < width && i < line.Length; i++)
{
map[i, lineCount] = line[i];
}
}
lineCount++;
}
file.Close();
return;
}
}
Here is my Maze class :
public class Maze
{
public static readonly char CHAR_WALL = '#';
public static readonly char CHAR_START = 'S';
public static readonly char CHAR_FINISH = 'F';
public int Width { get; internal set; }
public int Height { get; internal set; }
public int StartX { get; private set;}
public int StartY { get; private set; }
public int StartAngle { get; private set; }
private char[,] _plan;
public char[,] Plan { get { return _plan; } }
public Maze(char[,] plan)
{
}
Thanks for any reply, happy Eastern btw. :)
Something like this should allow you to load any rectangular dimension map:
public class MazeLoader : IMazeLoader
{
public Maze LoadMaze(string filepath)
{
char[][] loaded =
File
.ReadLines(filepath)
.Select(x => x.ToCharArray())
.ToArray();
int[] widths =
loaded
.Select(x => x.Length)
.Distinct()
.ToArray();
if (widths.Length != 1)
{
throw new InvalidDataException("Map Data Not Rectangular");
}
else
{
var width = widths[0];
var height = loaded.Length;
var map = new char[height, width];
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
map[i, j] = loaded[i][j];
return new Maze(map);
}
}
}
Now I tested this on this input:
aaaa
aaaa
bbbb
bbbb
bbbb
And got this map:
Please note that the file orientation and the map orientation are the same. I had to flip around how you were building our your map to get that to work.
Here's my alterations to Maze itself:
public class Maze
{
public int Width => this.Plan.GetUpperBound(1) - this.Plan.GetLowerBound(1) + 1;
public int Height => this.Plan.GetUpperBound(0) - this.Plan.GetLowerBound(0) + 1;
public char[,] Plan { get; private set; }
public Maze(char[,] plan)
{
this.Plan = plan;
}
}
I am using the TPL library to parallelize a 2D grid operation. I have extracted a simple example from my actual code to illustrate what I am doing. I am getting the desired results I want and my computation times are sped up by the number of processors on my laptop (12).
I would love to get some advice or opinions on my code as far as how my properties are declared. Again, it works as expected, but wonder if the design could be better. Thank you in advance.
My simplified code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Gridding
{
public abstract class Base
{
/// <summary>
/// Values representing the mesh values where each node in the gridis assigned som value.
/// </summary>
public float[,] Values { get; set; }
public abstract void Compute();
}
public class Derived : Base
{
/// <summary>
/// Make the mesh readonly. Is this necessary?
/// </summary>
readonly Mesh MyMesh;
Derived(Mesh mesh)
{
MyMesh = mesh;
}
public override void Compute()
{
Values = new float[MyMesh.NX, MyMesh.NY];
double[] xn = MyMesh.GetXNodes();
double[] yn = MyMesh.GetYNodes();
/// Paralellize the threads along the columns of the grid using the Task Paralllel Library (TPL).
Parallel.For(0, MyMesh.NX, i =>
{
Run(i, xn, yn);
});
}
private void Run(int i, double[] xn, double[] yn)
{
/// Some long operation that parallelizes along the columns of a mesh/grid
double x = xn[i];
for (int j = 0; j < MyMesh.NY; j++)
{
/// Again, longer operation here
double y = yn[j];
double someValue = Math.Sqrt(x * y);
Values[i, j] = (float)someValue;
}
}
static void Main(string[] args)
{
int nx = 100;
int ny = 120;
double x0 = 0.0;
double y0 = 0.0;
double width = 100;
double height = 120;
Mesh mesh = new Mesh(nx, ny, x0, y0, width, height);
Base tplTest = new Derived(mesh);
tplTest.Compute();
float[,] values = tplTest.Values;
Console.Read();
}
/// <summary>
/// A simple North-South oriented grid.
/// </summary>
class Mesh
{
public int NX { get; } = 100;
public int NY { get; set; } = 150;
public double XOrigin { get; set; } = 0.0;
public double YOrigin { get; set; } = 0.0;
public double Width { get; set; } = 100.0;
public double Height { get; set; } = 150.0;
public double DX { get; }
public double DY { get; }
public Mesh(int nx, int ny, double xOrigin, double yOrigin, double width, double height)
{
NX = nx;
NY = ny;
XOrigin = xOrigin;
YOrigin = yOrigin;
Width = width;
Height = height;
DX = Width / (NX - 1);
DY = Height / (NY - 1);
}
public double[] GetYNodes()
{
double[] yNodeLocs = new double[NY];
for (int i = 0; i < NY; i++)
{
yNodeLocs[i] = YOrigin + i * DY;
}
return yNodeLocs;
}
public double[] GetXNodes()
{
double[] xNodeLocs = new double[NX];
for (int i = 0; i < NX; i++)
{
xNodeLocs[i] = XOrigin + i * DX;
}
return xNodeLocs;
}
}
}
}
With only 100 to 150 array elements, parallelism setup overhead would offset the gains. You could cache the result of GetXNodes() and GetYNodes() and invalidate the cached values when XOrigin, NX, YOrigin or NY are modified.
I am trying to create a custom texture class, and I want to be able to choose if I the texture is 8bit or float a.k.a I want to be able to set _buffer to be either RGBFloat[] or RGBByte[] but I cant figure out how to do it with out making the whole class generic but if I do it generic it will be possible to set other object types other then just the ones that I want to limit it to. Maybe its possible to use inheritance or interface in some way, I don't know.
Example C# Code: (the places with T are not correct, just placeholder)
public struct RGBFloat
{
public float R { get; }
public float G { get; }
public float B { get; }
public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}
public struct RGBByte
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}
public enum TextureFormat
{
RGBFloat,
RGBByte
}
public class Texture2D
{
public int Width { get; }
public int Height { get; }
private T[] _buffer; // want it to be able to be either RGBFloat[] or RGBByte[] but nothing else.
public Texture2D(int width, int height, TextureFormat textureFormat)
{
Width = width;
Height = height;
switch (textureFormat)
{
case TextureFormat.RGBFloat:
_buffer = new RGBFloat[width * height];
break;
default:
_buffer = new RGBByte[width * height];
break;
}
}
public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}
Example of a working generic class I have created that is similar to my TextureClass but this one is meant to be able to support any object type.
public class Computebuffer<T>
{
public int Count { get; }
private T[] _buffer;
public Computebuffer(int count)
{
Count = count;
_buffer = new T[count];
}
public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public void Initialize(T value)
{
for (int i = 0; i < Count; i++)
{
_buffer[i] = value;
}
}
public void SetData(T[] data)
{
for (int i = 0; i < data.Length; i++)
{
_buffer[i] = data[i];
}
}
public void GetData(T[] data)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = _buffer[i];
}
}
public void Clear()
{
_buffer = new T[Count];
}
}
EDIT 1: (Updated version, almost working):
Issue: With this code I am able to add a RGBFloat to a Texture2D and that doesn't make sense. (see main program)
public interface IRGBType { }
public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }
public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}
public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}
public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private IRGBType[] _buffer;
public Texture2D(int width, int height)
{
Width = width;
Height = height;
_buffer = new IRGBType[width * height];
Initialize();
}
private void Initialize()
{
Type type = this.GetType();
if (type == typeof(RGBByte))
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = new RGBByte(0, 0, 0);
}
}
else
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = new RGBFloat(0, 0, 0);
}
}
}
public IRGBType this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public IRGBType this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}
MainProgram:
Texture2D<RGBFloat> texFloat = new Texture2D<RGBFloat>(64, 64);
Texture2D<RGBByte> texByte = new Texture2D<RGBByte>(64, 64);
texFloat[32, 32] = new RGBFloat(10, 50, 60);
texByte[32, 32] = new RGBFloat(0.9f, 0.24f, 0.5f); // this should not work I should not be able to add a RGBFloat to a RGBByte Texture2D
EDIT 2: (Updated version v3) still one issue, how would I Initialize _buffer array with an optional value, so new Texture2D<RGBFloat>(64, 64) should Initialize with new RGBFloat(0,0,0) and Texture2D<RGBFloat>(64, 64, new RGBFloat(0.5f,0.6f,0.7f)) should Initialize with value provided:
public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private T[] _buffer;
public Texture2D(int width, int height, T? initializeValue = null)
{
Width = width;
Height = height;
_buffer = new T[width * height];
Initialize(initializeValue);
}
private void Initialize(T? value)
{
Type type = this.GetType();
T rgb;
if (type == typeof(RGBFloat))
{
rgb = value ?? new RGBFloat(0, 0, 0); // Error: Operator '??' cannot be applied to operands of type 'T' and 'RGBFloat'
}
else
{
rgb = value ?? new RGBByte(0, 0, 0); // Error: Operator '??' cannot be applied to operands of type 'T' and 'RGBByte'
}
for(int i = 0; i < Width*Height; i++)
{
_buffer[i] = rgb;
}
}
public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}
EDIT 3: The full final version that now works correctly:
public interface IRGBType { }
public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }
public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}
public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}
public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private T[] _buffer;
public Texture2D(int width, int height, T? initializeValue = null)
{
Width = width;
Height = height;
_buffer = new T[width * height];
if (initializeValue.HasValue)
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = initializeValue.Value;
}
};
}
public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}
}
You can create an interface that your RGBFloat and RGBByte structs implement, and limit the generic type to that interface. The interface can just be a "marker", with nothing in it:
public interface IRGBType { }
public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }
public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}
public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}
You can then have your generic class only accept types that implement this interface:
public class Texture2D<T> where T: IRGBType
{
...
}
If you know that you'll always have this interface implemented by a struct, you can further restrict the generic:
public class Texture2D<T> where T: struct, IRGBType
{
...
}
EDIT: Make sure to use the generic T parameter everywhere in your class, not the interface. This is necessary to ensure type safety, otherwise your indexers can accept any IRGBType, which can be very problematic. Correct usage:
public class Texture2D<T> where T: struct, IRGBType
{
private T[] _buffer;
public Texture2D(int width, int height)
{
...
_buffer = new T[width * height];
...
}
public T this[int i]
{
get => _buffer[i];
set => _buffer[i] = value;
}
}
You can try using only one generic struct like this:
public struct RGB<T>
where T : struct,
IComparable, IFormattable, IConvertible,
IComparable<T>, IEquatable<T>
{
public T R { get; }
public T G { get; }
public T B { get; }
public RGB(T r, T g, T b)
{
R = r;
G = g;
B = b;
}
}
public class RGBComputeBuffer<T>
where T : struct,
IComparable, IFormattable, IConvertible,
IComparable<T>, IEquatable<T>
{
public int Count { get; private set; }
private RGB<T>[] _buffer;
public RGBComputeBuffer(int count)
{
_buffer = new RGB<T>[count];
Count = count;
}
public RGB<T> this[int i]
{
get { return _buffer[i]; }
set { if ( !_buffer[i].Equals(value) ) _buffer[i] = value; }
}
public void Initialize(RGB<T> value)
{
for ( int i = 0; i < Count; i++ )
_buffer[i] = value;
}
public void SetData(RGB<T>[] data)
{
Array.Resize(ref _buffer, data.Length);
Count = data.Length;
for ( int i = 0; i < data.Length; i++ )
_buffer[i] = data[i];
}
public void GetData(RGB<T>[] data)
{
Array.Resize(ref data, _buffer.Length);
for ( int i = 0; i < data.Length; i++ )
data[i] = _buffer[i];
}
public void Clear()
{
_buffer = new RGB<T>[Count];
}
}
Example of usage:
var bufferOfRGBByte = new RGBCompositeBuffer<byte>(100);
var bufferOfRGBFloat = new RGBCompositeBuffer<float>(100);
An interface would be your best bet. By having RGBFloat and RGBByte implement an interface then you can use that interface type in your array. It will also allow adding other RGB types later.
public interface IRGB
{
}
public struct RGBFloat : IRGB
{
public float R { get; }
public float G { get; }
public float B { get; }
public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}
public struct RGBByte : IRGB
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}
public enum TextureFormat
{
RGBFloat,
RGBByte
}
public class Texture2D
{
public int Width { get; }
public int Height { get; }
private IRGB[] _buffer; // want it to be able to be either RGBFloat[] or RGBByte[] but nothing else.
public Texture2D(int width, int height, TextureFormat textureFormat)
{
Width = width;
Height = height;
switch (textureFormat)
{
case TextureFormat.RGBFloat:
_buffer = new IRGB[width * height];
break;
default:
_buffer = new IRGB[width * height];
break;
}
}
public IRGB this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}
public IRGB this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}
If you want to access the R,G,B variables however you may need to add some kind of accessor methods/properties to the interface.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
So in a few words i'm getting an error whenever i run this
System.NullReferenceException
Ball.boxContent.get returned null
i get this error on this line
box1.Content.Add(Myballs[5]);
what I'm doing is creating balls of different colors,weight and material
adding them into a list called MyBalls
then
adding them from that list into a box(that has a property that is a list called Content)
after this is done I'm supposed to call some of the box function and calculate the weight and print what is inside. Not yet reached this stage as i cannot
any help would be greatly appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace Ball
{
class Ball
{
private string color;
private string material;
private double weight;
public string Color { get; set; }
public string Material { get; set; }
public double Weight { get; set; }
public Ball() { }
public Ball(string color, double weight, string material)
{
this.Color = color;
this.Material = material;
this.Weight = weight;
}
public bool changecolorbymorethanweight(string c, double w)
{
if (Weight >= w)
{
Color = c;
return true;
}
else return false;
}
public void printall()
{
Console.WriteLine("Η μπάλα είναι χρώματος {0}\nυλικού {1}\nκαι βάρους {2}", Color, Material, Weight);
}
}
-
class Box
{
private double height;
private double width;
private double length;
private string material;
public List<Ball> content = new List<Ball>();
private double weight;
public double Height { get; set; }
public double Width { get; set; }
public double Length { get; set; }
public string Material { get; set; }
public List<Ball> Content { get; set; }
public double Weight
{
get
{
double varos = 0;
for (int i = 0; i < content.Count; i++)
{
varos = varos + content[i].Weight;
}
weight = varos;
return weight;
}
set
{
Weight = weight;
}
}
public void removefirst3()
{
Content.RemoveAt(0);
Content.RemoveAt(1);
Content.RemoveAt(2);
}
public void removeall()
{
Content.Clear();
}
public void removeallbycolor(string rbc)
{
for (int i = 0; i < Content.Count; i++)
if (Content[i].Color == rbc)
Content.RemoveAt(i);
}
public int getnumberbycolor(string gnbc)
{
int counter = 0;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Color == gnbc)
counter++;
return counter;
}
public bool removeallmorethanbyweight(double rbwb)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Weight >= rbwb)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public bool removealllessthanbyweight(double rbws)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Weight >= rbws)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public bool removeallbymaterial(string rabm)
{
bool result = false;
for (int i = 0; i < Content.Count; i++)
if (Content[i].Material == rabm)
{
Content.RemoveAt(i);
result = true;
}
return result;
}
public void changecolorbyposition(int p, string c)
{
for (int i = 0; i < Content.Count; i++)
if (i == p)
Content[i].Color = c;
}
public void printall()
{
Console.WriteLine("Tο κουτί μας έχει \n{0} ύψος\n{1} πλάτος\n{2} μήκος\nείναι φτιαγμένο από {3}\nτο βάρος του είναι {4}\n και μέσα του έχει:\n{5}", Height, Width, Length, Material, Weight, Content);
}
public Box() { }
public Box(double length, double width, double height, string material, double weight, List<Ball> content)
{
this.Length = length;
this.Width = width;
this.Height = height;
this.Material = material;
this.Weight = weight;
this.Content = content;
}
public Box(double length, double width, double height, string material)
{
this.Length = length;
this.Width = width;
this.Height = height;
this.Material = material;
}
}
-
class Program
{
static void Main(string[] args)
{
Box box1 = new Box(1.2, 1.3, 1.8, "χάρτινο");
Box box2 = new Box(1.2, 2.3, 2.5, "ξύλινο");
Ball b1 = new Ball("Red", 2.5, "μεταλλική");
Ball b2 = new Ball("Red", 2.5, "μεταλλική");
Ball b3 = new Ball("Red", 2.5, "μεταλλική");
Ball b4 = new Ball("Red", 1.5, "μεταλλική");
Ball b5 = new Ball("Red", 1.5, "μεταλλική");
Ball b6 = new Ball("Black", 0.5, "πλαστική");
Ball b7 = new Ball("Black", 0.5, "πλαστική");
Ball b8 = new Ball("Black", 0.5, "πλαστική");
Ball b9 = new Ball("Black", 0.5, "πλαστική");
Ball b10 = new Ball("Black", 0.5, "πλαστική");
Ball b11 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b12 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b13 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b14 = new Ball("Άσπρο", 1.1, "λαστιχένια");
Ball b15 = new Ball("Άσπρο", 1.1, "λαστιχένια");
List<Ball> Myballs = new List<Ball>() { b1, b2 };
Myballs.Capacity = 15;
Myballs.Add(b1);
Myballs.Add(b2);
Myballs.Add(b3);
Myballs.Add(b4);
Myballs.Add(b5);
Myballs.Add(b6);
Myballs.Add(b7);
Myballs.Add(b8);
Myballs.Add(b9);
Myballs.Add(b10);
Myballs.Add(b11);
Myballs.Add(b12);
Myballs.Add(b13);
Myballs.Add(b14);
Myballs.Add(b15);
box1.Content.Add(Myballs[5]);
box1.Content.Add(Myballs[6]);
box1.Content.Add(Myballs[7]);
box1.Content.Add(Myballs[8]);
box1.Content.Add(Myballs[9]);
box1.Content.Add(Myballs[10]);
box1.Content.Add(Myballs[11]);
box1.Content.Add(Myballs[12]);
box1.Content.Add(Myballs[13]);
box1.Content.Add(Myballs[14]);
box2.Content.Add(Myballs[0]);
box2.Content.Add(Myballs[1]);
box2.Content.Add(Myballs[2]);
box2.Content.Add(Myballs[3]);
box2.Content.Add(Myballs[4]);
Console.ReadKey();
}
}
}
Initialize the Content property, either in the Box class:
public List<Ball> Content { get; set; } = new List<Ball>();
...or in the Main method before you add any balls:
box1.Content = new List<Ball>();
box1.Content.Add(Myballs[5]);
...
How do I put my four shapes into the object array I have created? Using
shapeArray[0] = (1,2,3,4)
is all i can think to do and this is obviously incorrect...
struct Shapes
{
private int width;
private int height;
private int xAxis;
private int yAxis;
}
Shapes[] shapeArray = new Shapes[4];
You should add a new constructor for your Shape:
struct Shape
{
public Shape(int width, int height, int xAxis, int yAxis)
{
this.width = width;
this.height = height;
this.xAxis = xAxis;
this.yAxis = yAxis;
}
private int width;
private int height;
private int xAxis;
private int yAxis;
public int Width { get { return width; } }
public int Height { get { return height; } }
public int XAxis { get { return xAxis; } }
public int YAxis { get { return yAxis; } }
}
Then you can use that to create it:
Shape[] shapes = new Shape[]{
new Shape(1, 2, 3, 4),
new Shape(2, 4, 6, 8),
new Shape(1, 2, 3, 4),
new Shape(4, 3, 2, 1)
};
Since you didn't create a constructor for Shapes you'll have to set the properties explicitly
shapeArray[0] = new Shapes;
shapeArray[0].width = 1;
shapeArray[0].height = 2;
shapeArray[0].xAxis = 3;
shapeArray[0].yAxis = 4;
HOWEVER the proper way to do this (and avoid having a mutable struct) is to privatize the public fields and add a constructor to your struct:
public Shapes(int width, int height, int xAxis, int yAxis)
{
this.width = width;
this.height = height;
this.xAxis = xAxis;
this.yAxis = yAxis;
}
Then you would just use
shapeArray[0] = new Shapes(1, 2, 3, 4);