How to create array of 100 new objects? - c#

I'm trying something like that:
class point
{
public int x;
public int y;
}
point[] array = new point[100];
array[0].x = 5;
and here's the error:
Object reference not set to an instance of an object. (# the last line)
whats wrong? :P

It only creates the array, but all elements are initialized with null.
You need a loop or something similar to create instances of your class.
(foreach loops dont work in this case)
Example:
point[] array = new point[100];
for(int i = 0; i < 100; ++i)
{
array[i] = new point();
}
array[0].x = 5;

When you do
point[] array = new point[100];
you create an array, not 100 objects. Elements of the array are null. At that point you have to create each element:
array[0] = new point();
array[0].x = 5;

You can change class point to struct point in that case new point[500] will create an array of points initialized to 0,0 (rather than array of null's).

As the other answers explain, you need to initialize the objects at each array location. You can use a method such as the following to create pre-initialized arrays
T[] CreateInitializedArray<T>(int size) where T : new()
{
var arr = new T[size];
for (int i = 0; i < size; i++)
arr[i] = new T();
return arr;
}
If your class doesn't have a parameterless constructor you could use something like:
T[] CreateInitializedArray<T>(int size, Func<T> factory)
{
var arr = new T[size];
for (int i = 0; i < size; i++)
arr[i] = factory();
return arr;
}
LINQ versions for both methods are trivial, but slightly less efficient I believe

int[] asd = new int[99];
for (int i = 0; i < 100; i++)
asd[i] = i;
Something like that?

Sometimes LINQ comes in handy. It may provide some extra readability and reduce boilerplate and repetition. The downside is that extra allocations are required: enumerators are created and ToArray does not know the array size beforehand, so it might need to reallocate the internal buffer several times. Use only in code whose maintainability is much more critical than its performance.
using System.Linq;
const int pointsCount = 100;
point[] array = Enumerable.Range(0, pointsCount)
.Select(_ => new point())
.ToArray()

Related

How to store object values in a jagged array in C# [duplicate]

I want to create array 10 * 10 * 10 in C# like int[][][] (not int[,,]).
I can write code:
int[][][] count = new int[10][][];
for (int i = 0; i < 10; i++)
{
count[i] = new int[10][];
for (int j = 0; j < 10; j++)
count[i][j] = new int[10];
}
but I am looking for a more beautiful way for it. May be something like that:
int[][][] count = new int[10][10][10];
int[][][] my3DArray = CreateJaggedArray<int[][][]>(1, 2, 3);
using
static T CreateJaggedArray<T>(params int[] lengths)
{
return (T)InitializeJaggedArray(typeof(T).GetElementType(), 0, lengths);
}
static object InitializeJaggedArray(Type type, int index, int[] lengths)
{
Array array = Array.CreateInstance(type, lengths[index]);
Type elementType = type.GetElementType();
if (elementType != null)
{
for (int i = 0; i < lengths[index]; i++)
{
array.SetValue(
InitializeJaggedArray(elementType, index + 1, lengths), i);
}
}
return array;
}
You could try this:
int[][][] data =
{
new[]
{
new[] {1,2,3}
},
new[]
{
new[] {1,2,3}
}
};
Or with no explicit values:
int[][][] data =
{
new[]
{
Enumerable.Range(1, 100).ToArray()
},
new[]
{
Enumerable.Range(2, 100).ToArray()
}
};
There is no built in way to create an array and create all elements in it, so it's not going to be even close to how simple you would want it to be. It's going to be as much work as it really is.
You can make a method for creating an array and all objects in it:
public static T[] CreateArray<T>(int cnt, Func<T> itemCreator) {
T[] result = new T[cnt];
for (int i = 0; i < result.Length; i++) {
result[i] = itemCreator();
}
return result;
}
Then you can use that to create a three level jagged array:
int[][][] count = CreateArray<int[][]>(10, () => CreateArray<int[]>(10, () => new int[10]));
With a little help from Linq
int[][][] count = new int[10].Select(x => new int[10].Select(x => new int[10]).ToArray()).ToArray();
It sure isn't pretty and probably not fast but it's a one-liner.
There is no 'more elegant' way than writing the 2 for-loops. That is why they are called 'jagged', the sizes of each sub-array can vary.
But that leaves the question: why not use the [,,] version?
int[][][] count = Array.ConvertAll(new bool[10], x =>
Array.ConvertAll(new bool[10], y => new int[10]));
A three dimensional array sounds like a good case for creating your own Class. Being object oriented can be beautiful.
You could use a dataset with identical datatables. That could behave like a 3D object (xyz = row, column, table)... But you're going to end up with something big no matter what you do; you still have to account for 1000 items.
Why don't you try this?
int[,,] count = new int[10, 10, 10]; // Multi-dimentional array.
Any problem you see with this kind of representation??

Problems with array declaration without set size

In Microsoft Visual Studio (Community Edition of course) I have a simple C# program where I declare a simple array without a set size like so
int[] paths;
In a later part of the program I try to set parts of the array but it gives me an error
Use of unsigned local variable 'paths'
in this part of the program
for (int b = 0; b < 100; b++) {
paths[b] = b;
}
In conclusion, I suppose I'm wondering whether this problem that affects just me, or a problem of syntax. (I originated from Java which is half to blame how I ran into this question) I am willing to accept closure on whether this is possible or not,(If so source please) or If I'm just doing it wrong.(If so please provide a solution/suggestions in comments)
In C# Arrays are fixed size, and need to be initialized
var size = 100;
int[] paths = new int[size];
for (var b = 0; b < size; b++) {
paths[b] = b;
}
List is also another good thing for a C# beginner to know about, the difference between an array and a list, is that a List will resize itself for you automagically (I believe there is a very similar List class in Java)
var size = 100;
var paths = new List<int>();
for (var b = 0; b < size; b++) {
paths.Add(b);
}
You just declared the array, but you also need to create it before using it:
paths = new int[100];
You must follow the array declaration syntax.
int[] paths; //-> here you are declaring the paths array and your not creating array.
in memory it set paths array without its sizes. So you must set the size by creating this array as follows.
int[] paths = new int[10];
you can create and declare array like as follows, for to assign another array with it.
EG:
int[] arr1 = new int[] { 0,1,2,3,4,5,6,7};
int[] paths =arr1;
here arr1 size and data will be automatically assigned to paths array.
Firstly you are creating a variable but you have not assigned it at all, this is the reason for you error.
Secondly in C# arrays require a fixed size and can not be resized so when initializing a size must be provided, either explicitly as below or implicitly by initializing it with objects (see comments).
int[] paths; // declaration
paths = new int[100] // assignment, array initialized with a size of 100
// with objects
// paths = new int[] { 1, 2, 3 };
// declaration and assignment can also be merged into 1 line.
// i.e int[] paths = new int[100]
for (int b = 0; b < 100; b++) {
paths[b] = b;
}
you must declare and initialize the array element in your code like
int[] myInt = new int[100]
If you don't know the size before initialize you need to use List like
List<int> list = new List<int>();
list.Add(123);
list.Add(456);
list.Add(789);
Console.WriteLine(list[2]);
and it is necessary to use array and size of array is not fixed before initialize you need to follow below code but below code is wastage of memory usage and more execution process. so my recommend is use List instead of int[]
// Global Variable
int[] myInt;
int mySize = 1;
private void button1_Click(object sender, EventArgs e)
{
if (mySize > 1)
{
int[] tempInt = new int[mySize];
tempInt = myInt;
myInt = new int[mySize];
for (int i = 0; i < mySize - 1; i++)
{
myInt[i] = tempInt[i];
}
myInt[mySize - 1] = mySize;
}
else
{
myInt = new int[mySize];
myInt[mySize - 1] = mySize;
}
mySize++;
}

Creating a big array C#

I'm very, very new to C# and would like to ask a maybe very stupid question, the first language I learned was Java, in which I could do this:
int[][] array = new int[1600][900];
array[600][400] = 10;
for(int x = 0; x < 1600; x++)
{
for(int y = 0; y < 900; y++)
{
int something = colour[x][y];
}
}
Now I've searched the web for quite a while, but I've got no idea about how to do this in C#
EDIT:
Thanks for the help everyone, it's been usefull :)
Just use a comma :
int[,] array = new int[1600,900];
array[600,400] = 10;
//...
You can do it in a very similar way in C#:
int[,] array = new int[1600,900];
array[600,400] = 10;
for(int x = 0; x < 1600; x++)
{
for(int y = 0; y < 900; y++)
{
int something = colour[x,y];
}
}
I'm not sure if I understand what's the purpose of the code in the double for cycle. I suppose those three pieces of code don't have anything in common.
int [,] array = new int[1600,900];
To add some color to the answers:
In .NET, an int[][] is a jagged array, or an array of arrays. While this may be a perfectly good structure for you to use, it has the addded overhead that each array must be initialized individually. So your initialization would be:
int[][] array = new int[1600][];
for(int i=0;i<array.Length;i++)
array[i] = new int[900];
now you can access an individual value by using
array[600][400] = 10;
One benefit of using jagged arrays is that the "interior" array can be different sizes. If you don;t need that flexibility than using a rectangular ([,]) array may be a better option for you.

Initialize an array (string or any other data type) inside a Struct

I'm looking to do this in C#.
public struct Structure1
{ string string1 ; //Can be set dynamically
public string[] stringArr; //Needs to be set dynamically
}
In general, how should one initialize an array dynamically if need be?
In simplest of terms, I'm trying to achieve this in C#:
int[] array;
for (int i=0; i < 10; i++)
array[i] = i;
Another example:
string[] array1;
for (int i=0; i < DynamicValue; i++)
array1[i] = "SomeValue";
First off, your code will almost work:
int[] array = new int[10]; // This is the only line that needs changing
for (int i=0; i < 10; i++)
array[i] = i;
You could potentially initialize your arrays within your struct by adding a custom constructor, and then initialize it calling the constructor when you create the struct. This would be required with a class.
That being said, I'd strongly recommend using a class here and not a struct. Mutable structs are a bad idea - and structs containing reference types are also a very bad idea.
Edit:
If you're trying to make a collection where the length is dynamic, you can use List<T> instead of an array:
List<int> list = new List<int>();
for (int i=0; i < 10; i++)
list.Add(i);
// To show usage...
Console.WriteLine("List has {0} elements. 4th == {1}", list.Count, list[3]);
int[] arr = Enumerable.Range(0, 10).ToArray();
update
int x=10;
int[] arr = Enumerable.Range(0, x).ToArray();
// IF you are going to use a struct
public struct Structure1
{
readonly string String1;
readonly string[] stringArr;
readonly List<string> myList;
public Structure1(string String1)
{
// all fields must be initialized or assigned in the
// constructor
// readonly members can only be initialized or assigned
// in the constructor
this.String1 = String1
// initialize stringArr - this will also make the array
// a fixed length array as it cannot be changed; however
// the contents of each element can be changed
stringArr = new string[] {};
// if you use a List<string> instead of array, you can
// initialize myList and add items to it via a public setter
myList = new List<string>();
}
public List<string> StructList
{
// you can alter the contents and size of the list
get { return myList;}
}
}

Redim Preserve in C#?

I was shocked to find out today that C# does not support dynamic sized arrays. How then does a VB.NET developer used to using ReDim Preserve deal with this in C#?
At the beginning of the function I am not sure of the upper bound of the array. This depends on the rows returned from the database.
VB.NET doesn't have the idea of dynamically sized arrays, either - the CLR doesn't support it.
The equivalent of "Redim Preserve" is Array.Resize<T> - but you must be aware that if there are other references to the original array, they won't be changed at all. For example:
using System;
class Foo
{
static void Main()
{
string[] x = new string[10];
string[] y = x;
Array.Resize(ref x, 20);
Console.WriteLine(x.Length); // Prints out 20
Console.WriteLine(y.Length); // Still prints out 10
}
}
Proof that this is the equivalent of Redim Preserve:
Imports System
Class Foo
Shared Sub Main()
Dim x(9) as String
Dim y as String() = x
Redim Preserve x(19)
Console.WriteLine(x.Length)
Console.WriteLine(y.Length)
End Sub
End Class
The two programs are equivalent.
If you truly want a dynamically sized collection, you should use List<T> (or something similar). There are various issues with using arrays directly - see Eric Lippert's blog post for details. That's not to say you should always avoid them, by any means - but you need to know what you're dealing with.
Use ArrayLists or Generics instead
Use a List<T>. It will dynamically size as needed.
You really shouldn't be using ReDim, it can be very expensive. I prefer List(Of T), but there are many options in this area.
That said, you had a question and here is your answer.
x = (int[]) Utils.CopyArray((Array) x, new int[10]);
I couldn't help but notice that none of the above answers approach the concept of multidimensional arrays. That being said, here's an example. The array in question is predefined as x.
int[,] temp = new int[newRows, newCols];
int minRows = Math.Min(newRows, x.GetUpperBound(0) + 1);
int minCols = Math.Min(newCols, x.GetUpperBound(1) + 1);
for (int i = 0; i < minRows ; ++i)
for (int j = 0; j < minCols; ++j)
temp[i, j] = x[i, j];
x = temp;
Just for fun, here's one way to use generics in order to redim/extend a unidimensional array (add one more "row") :
static T[] Redim<T>(T[] arr, bool preserved)
{
int arrLength = arr.Length;
T[] arrRedimed = new T[arrLength + 1];
if (preserved)
{
for (int i = 0; i < arrLength; i++)
{
arrRedimed[i] = arr[i];
}
}
return arrRedimed;
}
And one to add n rows (though this doesn't prevent user from undersizing the array, which will throw an error in the for loop) :
static T[] Redim<T>(T[] arr, bool preserved, int nbRows)
{
T[] arrRedimed = new T[nbRows];
if (preserved)
{
for (int i = 0; i < arr.Length; i++)
{
arrRedimed[i] = arr[i];
}
}
return arrRedimed;
}
I'm sure you get the idea.
For a multidimensional array (two dimensions), here's one possibility:
static T[,] Redim<T>(T[,] arr, bool preserved)
{
int Ubound0 = arr.GetUpperBound(0);
int Ubound1 = arr.GetUpperBound(1);
T[,] arrRedimed = new T[Ubound0 + 1, Ubound1];
if (preserved)
{
for (int j = 0; j < Ubound1; j++)
{
for (int i = 0; i < Ubound0; i++)
{
arrRedimed[i, j] = arr[i, j];
}
}
}
return arrRedimed;
}
In your program, use this with or even without the type specified, the compiler will recognize it :
int[] myArr = new int[10];
myArr = Redim<int>(myArr, true);
or
int[] myArr = new int[10];
myArr = Redim(myArr, true);
Not sure if all this is really relevant though. =D
Please feel free to correct me or improve my code. ;)
Even though it's a long time ago it might help someone looking for a simple solution - I found something great in another forum:
//from Applied Microsoft.NET framework Programming - Jeffrey Richter
public static Array RedimPreserve(Array origArray, Int32 desiredSize)
{
System.Type t = origArray.GetType().GetElementType();
Array newArray = Array.CreateInstance(t, desiredSize);
Array.Copy(origArray, 0, newArray, 0, Math.Min(origArray.Length, desiredSize));
return newArray;
}
Source: https://social.msdn.microsoft.com/Forums/en-US/6759816b-d525-4752-a3c8-9eb5f4a5b194/redim-in-c?forum=csharplanguage

Categories